所以这就是我在Android中使用晕影样式效果(图像是位图):
public void vignette() {
float radius = (float) (image.getWidth()/1.5);
RadialGradient gradient = new RadialGradient(image.getWidth()/2, image.getHeight()/2, radius, Color.TRANSPARENT, Color.BLACK, Shader.TileMode.CLAMP);
Canvas canvas = new Canvas(image);
canvas.drawARGB(1, 0, 0, 0);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setShader(gradient);
final Rect rect = new Rect(0, 0, image.getWidth(), image.getHeight());
final RectF rectf = new RectF(rect);
canvas.drawRect(rectf, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(image, rect, rect, paint);
}
这“有效”,但有一些问题。首先,这不是一个真正的插图,它只是一个渐变,所以你可以看到黑色的几乎一直到中心,而不是靠近边缘羽化。
使用的RadialGradient也只允许设置圆的半径而不是椭圆。椭圆将能够更有效地匹配非方形图像的尺寸而不是圆形。
渐变的质量也不是很好。
我正在尝试从ImageMagick复制vignetteImage方法(我指的是php版本)。我在PHP中使用此代码生成我想要的图像样式:
$im = new IMagick('city.png');
$im->vignetteImage($width/1.5, 350, 20, 20);
我尝试使用NDK构建ImageMagick但是在正确链接各种图像库方面没有成功(我只使用gif支持成功构建但没有png,jpeg或tiff)。
我还附上了一张图片,比较了上面显示的两种方法。左边的图像是通过php使用ImageMagick生成的,右边的图像是使用上面针对Android显示的方法生成的。
答案 0 :(得分:4)
如果你仔细看左边的图像,tf使用Alpha(透明度)与右边图像的指数增长,这是非常线性的。
显然Shader.TitleMode.CLAMP
是线性函数。您应该做的是使用RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)在图像上定义10个或更多点,颜色值呈指数递减(从黑色到透明)。
答案 1 :(得分:1)
我知道这是一个古老的讨论,但它可能对某人有帮助。 您可以使用AccelerateInterpolator生成Taranfx提到的点,它会锁定很棒。