【问题标题】:ImageView ColorFilter on non tranparent pixels. Clip非透明像素上的 ImageView ColorFilter。夹子
【发布时间】:2012-08-15 10:51:11
【问题描述】:

我有一个带有位图的 ImageView。此位图具有 Alpha 通道和透明像素。 当我尝试将 ColorFiter 与 Mode.OVERLAY (因为蜂窝)一起使用时 - 提供颜色覆盖整个图像视图(整个矩形),但我只想覆盖非透明像素。如何剪辑 imageview 的画布以在我想要的地方执行过滤器?

更新

我在 png 中有灰色图像:

当我尝试使用 MODE_ATOP 时,我得到:

当我使用 OVERLAY 时,我得到:

我想得到什么:

【问题讨论】:

    标签: android image mask clip


    【解决方案1】:

    可能有一种更有效的方法来做到这一点(也许通过创建一个ColorMatrixColorFilter 来近似它),但由于Mode.OVERLAY 似乎是hard to simplify otherwise,这里有一些示例代码应该实现你想要的:

    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 组合它以​​不绘制透明像素。

    原图:

    结果:

    【讨论】:

    • 谢谢,我现在就试试,如果您现在如何使用颜色矩阵来实现这一点,您能否提供有关如何执行此操作的教程/示例/文档的链接?
    • 我试过你的样本,但结果不是预期的,我已经用图片粘贴了更新的问题
    • 嗯..我似乎得到了你想要的结果,让我把截图上传到我的答案中。
    • 非常感谢,这太完美了!
    【解决方案2】:

    您可以使用 Overlay 模式,然后使用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多