2011-06-24 121 views
2

我正在尝试使用Android Path类创建'发光效果'。但是,渐变不会弯曲以适应路径。相反,它只是简单地显示在“上方”,并被剪裁到路径的中风。使用方形路径,下面的图像显示了我的意思是:沿路径使用渐变

Path-gradient fail

相反,应该看起来更像是这样的:

enter image description here

换句话说,梯度遵循的路径,特别是根据CornerPathEffect中设置的半径包裹角落。

这里是代码的相关部分:

paint = new Paint(); 
paint.setStyle(Style.STROKE); 
paint.setStrokeWidth(20); 
paint.setAntiAlias(true); 
LinearGradient gradient = new LinearGradient(30, 0, 50, 0, 
    new int[] {0x00000000, 0xFF0000FF, 0x00000000}, null, Shader.TileMode.MIRROR); 
paint.setShader(gradient); 
PathEffect cornerEffect = new CornerPathEffect(10); 
paint.setPathEffect(cornerEffect); 
canvas.drawPath(boxPath, paint); 

任何想法?


另一种方法是在定义笔画宽度时获得“软边刷”效果。我已经尝试过BlurMaskFilters,但是它们给出了统一的模糊效果,而不是从不透明到透明的过渡。有谁知道这是可能的吗?

回答

3

原来这样做有一个愚蠢的显而易见的方法。只需重新使用相同的路径,并调整每个绘图遍的笔触宽度和alpha。示例代码:

float numberOfPasses = 20; 
float maxWidth = 15; 
for (float i = 0; i <= numberOfPasses; i++){ 
    int alpha = (int) (i/numberOfPasses * 255f); 
    float width = maxWidth * (1 - i/numberOfPasses); 

    paint.setARGB(alpha, 0, 0, 255); 
    paint.setStrokeWidth(width); 
    canvas.drawPath(path, paint); 
} 

查看下面的结果示例。使用此方法绘制左侧路径,用于比较的右侧路径使用maxWidth和255 alpha绘制在单个笔划中。

Example of drawing result

这主要工作。有两个问题:

  • 渐变不如它可能光滑。这是因为每次通过都会导致alpha的建立速度过快,在最终的中风之前达到255。尝试一下int alpha = (int) (i/numberOfPasses * 125f);(注意改为125f而不是255f)会有所帮助。

  • 该路径看起来像是在角落的内部“切割”。可能应用CornerPathEffect的一些结果。

+0

嘿史蒂夫 - 上周我发现了同样的想法,事实上,当我的头脑在漫长的驾驶中感到无聊时,我现在因为不记得在这里提到它而踢自己了!不过,我很高兴你已经尝试过并发现它能够工作,并且了解你遇到的问题很有趣。感谢您分享您的代码。我会在我的SVG解析器中添加类似的东西,我可能会定义自己的自定义名称空间XML标记以在特定路径上触发此功能。辉煌的工作 - +1! – Trevor

+0

该alpha应该是'255/numberOfPasses',不乘以'i' – njzk2

1

如果我理解正确的话,你想要做的是让渐变有效地形成笔画的“笔刷”。

这是究竟是我最近也在努力实现的,但据我所知,API并没有提供任何直接的方法来做到这一点。我最近为Android Canvas转换器类创建了一个SVG,因此我最近也在Inkscape中做了很多工作。所以,当我仔细研究它时,我想知道Inkscape是否可以做到这一点。但是,即使在Inkscape中,这也是一件非常不重要的事情。后被用下面的下载链接教程沿路径的过程中,进行一些搜索我碰到一个梯度的这一形象终于来了,一起:

http://www.flickr.com/photos/[email protected]/3312087295/

我亲自尝试在做的时候就是创造出一些半圆形,其中的路径是一种霓虹辉光,而不是平坦的颜色。就Android API和SVG标准而言,似乎唯一的方法就是创建一个在圆上完美居中的径向渐变,并在恰当的位置放置一系列色块。做起来相当棘手,我当然不知道你会如何做到像广场那样的形状。

对不起,这是一个'我做不到',而不是一个有用的答案!随着我渴望了解一种“软笔刷”效果的解决方案,我会对此感兴趣。

+0

嗯,很高兴知道我不是唯一一个努力寻找一个解决这个:P的我能想到的唯一剩下的解决方案就是写一个数学公式的野兽,它给出了一条路径,创造了一条与之相邻的路径。然后用不同的减少不透明度的“涂料”手动绘制几次。这听起来像一个巨大的闪光,但我认为我在某个地方看到,Android团队使用类似的方法来处理Android Market的图形。 –

+0

结果发现有一种愚蠢的做法 - 如果你仍然对此感兴趣,请参阅下面的答案。另外,我偶然发现了我在之前的评论中提到的关于Android团队如何在Android电子市场中大肆宣传的文章:http://www.pushing-pixels.org/2010/12/15/meet-the-green- goblin-part-3.html –

4

如何使用软刷位图进行绘图?使用像Photoshop这样的图像编辑软件制作一个不透明度随着径向向外减小的软圆刷。另存为drawable,将其加载到位图中并沿着路径均匀地绘制它。用白色的笔刷制作位图。这样,您可以简单地使用PorterDuffColorFilter将给定的颜色(这里是蓝色)与您的位图相乘。

brush1=BitmapFactory.decodeResource(getResources(), R.drawable.brush_custom_one); 
//This contains radially decreasing opacity brush 
porter_paint.setColorFilter(new PorterDuffColorFilter(paint.getColor(), Mode.MULTIPLY)); 
for (int i=1;i<matrix.size();i++) { 
//matrix contains evenly spaced points along path 
Point point = matrix.get(matrix.get(i)); 
canvas.drawBitmap(brush1, point.x,point.y, porter_paint);} 

使用的刷(它的存在):Brush used 最终的结果是:Final result

+1

这是另一个可能相当不错的解决方案。下次我需要做这样的事情时,我会研究它。 (这个线程是2岁) –