这就是我在 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 生成的。
最佳答案
如果您仔细观察左图,tf 使用的 Alpha(透明度)呈指数增长,而右图是非常线性的。
显然 Shader.TitleMode.CLAMP
是一个线性函数。你应该做的是使用 RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)在图像上定义 10 个或更多点,颜色值呈指数递减(黑色到透明)。
或者,您可以引用 ICS 画廊的画廊 3d 源 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.1_r1/com/android/gallery3d/photoeditor/filters/VignetteFilter.java?av=h
关于android - Android 中的小插图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10658828/