Android中的小插图

时间:2012-05-18 19:47:54

标签: android image-processing

所以这就是我在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显示的方法生成的。

left: vignette from php/ImageMagick. right: vignette from Android using method shown above

2 个答案:

答案 0 :(得分:4)

如果你仔细看左边的图像,tf使用Alpha(透明度)与右边图像的指数增长,这是非常线性的。

显然Shader.TitleMode.CLAMP是线性函数。您应该做的是使用RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)在图像上定义10个或更多点,颜色值呈指数递减(从黑色到透明)。

或者,您可以参考ICS图库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

的图库3d来源

答案 1 :(得分:1)

我知道这是一个古老的讨论,但它可能对某人有帮助。 您可以使用AccelerateInterpolator生成Taranfx提到的点,它会锁定很棒。