Android如何在ImageView上应用蒙版?

Ang*_*raX 33 android android-imageview

所以我从这里尝试了代码:用掩码创建一个ImageView.我使用以下图像作为原始和掩码:

在此输入图像描述在此输入图像描述

但是,我得到的结果是这样的:

在此输入图像描述

请注意,窗口背景不是黑色,而是全息光(在星系连接上看起来像一个非常浅的灰色,而不是完全白色).第二个图像是在列表视图中选择项目时得到的结果.

相反,如果我使用相同的算法创建一个新的位图,然后将其传递给图像视图而不是覆盖onDraw(),它会正确绘制:

Canvas canvas = new Canvas();
Bitmap mainImage = //get original image
Bitmap maskImage = //get mask image
Bitmap result = Bitmap.createBitmap(mainImage.getWidth(), mainImage.getHeight(), Bitmap.Config.ARGB_8888);

canvas.setBitmap(result);
Paint paint = new Paint();
paint.setFilterBitmap(false);

canvas.drawBitmap(mainImage, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(maskImage, 0, 0, paint);
paint.setXfermode(null);

imageView.setImageBitmap(result);
Run Code Online (Sandbox Code Playgroud)

我得到了预期的结果:

在此输入图像描述

请注意,正确应用了淡入淡出.选择时,这一点更为明显.

那么ImageView的onDraw方法是如何创建这个黑色背景而不是让窗口背景显示的呢?有趣的是,如果原始图像本身具有一定的透明度,则该透明度得到尊重,例如:

在此输入图像描述

我自己无法弄明白.我宁愿能够在onDraw上进行,而不是预先创建位图,因为它只适用于位图作为源和掩码.我希望能够使用其他可绘制的内容,如渐变和纯色,但在这些情况下,宽度和高度未设置.

mor*_*h85 28

在研究了所有的stackoverflow帖子之后,我找到了创建没有黑色边框的遮罩的完美组合.它很适合我的目的.

目前我正在使用一个普通图像和一个屏蔽图像(一个带透明度的png)创建一个可拖动的视图,所以我需要覆盖onDraw函数.

private Bitmap mImage = ...;
private Bitmap mMask = ...;  // png mask with transparency
private int mPosX = 0;
private int mPosY = 0;

private final Paint maskPaint;
private final Paint imagePaint;

public CustomView (final Context context) {
    maskPaint = new Paint();
    maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

    imagePaint = new Paint();
    imagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
}

/* TODO
 if you have more constructors, make sure you initialize maskPaint and imagePaint
 Declaring these as final means that all your constructors have to initialize them.
 Failure to do so = your code won't compile.
*/

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();      
    canvas.drawBitmap(mMask, 0, 0, maskPaint);
    canvas.drawBitmap(mImage, mPosX, mPosY, imagePaint);
    canvas.restore();
}
Run Code Online (Sandbox Code Playgroud)