Android 如何有效地提取位图的可见区域?

Android 如何有效地提取位图的可见区域?,android,graphics,bitmap,Android,Graphics,Bitmap,我有一个位图,希望创建并使用一个过滤器,该过滤器将获取位图的所有可见部分(alpha!=0的所有像素),并在Android视图上绘制时将其设置为特定值 我能够通过位图上的简单for循环实现这一点: private int maskAlpha = 0xAA; private Paint maskPaint; private Bitmap targetViewLayoutBitmap; public CustomView(Context context, AttributeSet attrs, i

我有一个位图,希望创建并使用一个过滤器,该过滤器将获取位图的所有可见部分(alpha!=0的所有像素),并在Android视图上绘制时将其设置为特定值

我能够通过位图上的简单for循环实现这一点:

private int maskAlpha = 0xAA;
private Paint maskPaint;
private Bitmap targetViewLayoutBitmap;

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    maskPaint.setColor(Color.argb(maskAlpha, 0, 0, 0));
}

...

private void setTargetViewLayoutBitmap(final Bitmap viewBmp) {
    for (int x = 0; x < viewBmp.getWidth(); x++) {
        for (int y = 0; y < viewBmp.getHeight(); y++) {
            int pixel = viewBmp.getPixel(x, y);
            boolean isVisiblePixel = ((pixel & 0xff000000) != 0);
            targetViewLayoutBitmap.setPixel(x, y, isVisiblePixel ? 0x00ffffff : 0xff000000); 
        }
    }
}

@Override
protected void onDraw(Canvas canvas) {
    ...
    canvas.drawBitmap(targetViewLayoutBitmap, targetViewLeft, targetViewTop, viewMaskPaint);
}
private int maskAlpha=0xAA;
私人涂料;
私有位图targetViewLayoutBitmap;
公共自定义视图(上下文上下文、属性集属性、int-defStyleAttr){
super(上下文、attrs、defStyleAttr);
maskPaint=新油漆(油漆.防油漆别名标志);
maskPaint.setColor(Color.argb(maskAlpha,0,0,0));
}
...
私有void setTargetViewLayoutBitmap(最终位图视图BMP){
对于(int x=0;x

有没有更有效的方法来实现这一点?

您可以将
PorterDuff.Mode.SRC_与
中的
PorterDuff.Mode.SRC_一起使用

此示例采用可绘制的
并将每个不透明像素更改为绿色:

drawable.setColorFilter(new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN));
注意:您可以轻松地将其应用于
位图
并使用

Drawable drawable = new BitmapDrawable(getResources(), yourBitmap);

您可以将
PorterDuff.Mode.SRC_与
中的
PorterDuff.Mode.SRC_一起使用

此示例采用可绘制的
并将每个不透明像素更改为绿色:

drawable.setColorFilter(new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN));
注意:您可以轻松地将其应用于
位图
并使用

Drawable drawable = new BitmapDrawable(getResources(), yourBitmap);

经过一些测试,我找到了下面的解决方案,使用ColorMatrixColorFilter以最佳方式工作(应用矩阵所需的时间少于for循环的1/20)


感谢@Selvin为我指出了正确的方向(此解决方案是对您建议的解释)。

经过一些测试,我发现下面的解决方案使用ColorMatrixColorFilter以最佳方式工作(应用矩阵所需的for循环少于1/20)


感谢@Selvin为我指明了正确的方向(此解决方案解释了您的建议)。

一个get/setPixels调用,而不是多个get/setPixel调用setTargetViewLayoutBitmap@Selvin-我想这可能会让事情变得更快(另一方面也会带来内存成本)。我想要的答案可能是使用ColorMatrix或PorterDuffColorFilter,因为它们可以使用硬件加速。您是否尝试过ColorMatrix:
[0,0,0,0,255,0,0,0,0,0,0,255,0,0,0,0,0,255,0,0,0,0,255,0]
?但它会产生
isVisiblePixel?0x00ffffff:0xffffffff
。。。编辑:
[0,0,0,-256,255,0,0,0,0,-256,255,0,0,-256,255,0,0,0,0,255,0]
为什么?alpha=0,则您需要0x00ffffff,否则0xff000000。。。对于新的RGB通道=>
钳位(alpha*(-256)+255)
={0表示alph>0;255表示alpa==0}。。。。对于新的alpha通道
钳位(alpha*255+0)
={255表示alpha>0;0表示alpha==0}@Selvin,仅为了理解,-256在矩阵上下文中是什么意思?一个get/setPixels调用,而不是多个get/setPixel调用setTargetViewLayoutBitmap@Selvin-我想这会让事情变得更快(另一方面需要内存)。我要找的答案可能是使用ColorMatrix或PorterDuffColorFilter,因为它们可以使用硬件加速。您是否尝试过ColorMatrix:
[0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,0,255,0,0,0,255,0]
?但它会产生
isVisiblePixel?0x00ffffff:0xffffffff
…编辑:
[0,0,0,-256,255,0,0,0,0,0,-256,255,0,0,0,0,0,255,0]
为什么?alpha=0,那么你需要0x00FFFFFFFF否则0xff000000…用于新的RGB通道=>
钳制(alpha*(-256)+255)
={0表示alph>0;255表示alpa==0},….对于新的alpha通道
clamp(alpha*255+0)
={255表示alpha>0;0表示alpha==0}@Selvin,为了理解,-256在矩阵的上下文中是什么意思?呵呵,我的建议正好相反:)…我为
isVisiblePixel?0x00ffffff:0xff000000
给出了解决方案,
isVisiblePixel?0xff000000:0x00ffffff
:)呵呵,我的建议正好相反:)…我为
isVisiblePixel?0x00ffffff:0xff000000
给出了解决方案