非透明像素上的ImageView颜色过滤器。剪辑

4
我有一个ImageView和一个包含alpha通道和透明像素的位图。当我尝试使用Mode.OVERLAY的ColorFilter时(从蜂窝版本开始),提供的颜色覆盖了整个ImageView(整个矩形),但我只想覆盖非透明像素。如何剪切ImageView的画布以在需要的地方执行滤镜?
更新:
我有一个灰度png图片:
当我尝试使用MODE_ATOP时,我得到:
当我使用OVERLAY时,我得到:
而我想要得到的是:
3个回答

4

也许有更有效的方法来完成这个任务(可能是通过创建一个ColorMatrixColorFilter来近似它),但是由于Mode.OVERLAY似乎很难以其他方式简化,所以这里是一些示例代码,可以实现你想要的效果:

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final ImageView imageView = new ImageView(this);
        setContentView(imageView);

        final Paint paint = new Paint();
        Canvas c;

        final Bitmap src = BitmapFactory.decodeResource(getResources(),
                android.R.drawable.sym_def_app_icon);
        final int overlayColor = Color.RED;

        final Bitmap bm1 = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Config.ARGB_8888);
        c = new Canvas(bm1);
        paint.setColorFilter(new PorterDuffColorFilter(overlayColor, PorterDuff.Mode.OVERLAY));
        c.drawBitmap(src, 0, 0, paint);

        final Bitmap bm2 = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Config.ARGB_8888);
        c = new Canvas(bm2);
        paint.setColorFilter(new PorterDuffColorFilter(overlayColor, PorterDuff.Mode.SRC_ATOP));
        c.drawBitmap(src, 0, 0, paint);

        paint.setColorFilter(null);
        paint.setXfermode(new AvoidXfermode(overlayColor, 0, Mode.TARGET));
        c.drawBitmap(bm1, 0, 0, paint);

        imageView.setImageBitmap(bm2);
    }

}

简而言之,我们使用OVERLAY模式绘制源位图和颜色,然后使用第二个位图(使用SRC_ATOP模式合成),使用AvoidXfermode将其组合以不覆盖透明像素。

原始图片:

original image

结果:

result


谢谢,我现在就试试。如果您知道如何使用颜色矩阵实现这一点,能否给出有关如何执行此操作的教程/示例/文档的链接? - dilix
我尝试了你的示例,但结果并不如预期。我已经附上了带有图片的更新问题。 - dilix
嗯...我似乎得到了你想要的结果,让我将截图上传到我的答案中。 - Joe
1
这里有一篇关于ColorMatrixColorFilter的好信息的帖子:https://dev59.com/PW855IYBdhLWcg3wbjnO。 - Joe

1

您可以使用覆盖模式,然后使用DST_ATOP xFerMode剪切出曾经透明的区域,并使用相同的位图进行覆盖。https://developer.android.com/reference/android/graphics/PorterDuff.Mode

private fun applyFilterToImage() {

    val bitmapCopy = Bitmap.createBitmap(originalImage.width, originalImage.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmapCopy)

    val rnd = java.util.Random()
    val randomColor = Color.rgb(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))

    val paint = Paint()
    val porterDuffMode = PorterDuff.Mode.OVERLAY
    paint.colorFilter = PorterDuffColorFilter(randomColor, porterDuffMode)

    val maskPaint = Paint()
    maskPaint. xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)

    canvas.drawBitmap(originalImage, 0f, 0f, paint)

    canvas.drawBitmap(originalImage, 0f, 0f, maskPaint) //clips out the background that used to be transparent.

    imageView.setImageBitmap(bitmapCopy)
}

MarkerColorChangeGIF

的内容与编程有关。

0

在我的情况下,合并两个位图层:

    final Paint paint = new Paint();
    final Bitmap dst_bmp = Bitmap.createBitmap(front_bmp.getWidth(), front_bmp.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(dst_bmp);
    paint.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP));
    canvas.drawBitmap(black_bmp, 0, 0, null);
    canvas.drawBitmap(front_bmp, 0, 0, paint);

https://www.programming-books.io/essential/android/porterduff-mode-88a01690089945b4b2c505d1873e87e1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接