我有一个掩码位图,一半是红色,一个是透明的像这个https://www.dropbox.com/s/931ixef6myzusi0/s_2.png
我想使用掩码位图在画布上绘制只在红色区域可见的内容,代码如下:
Paint paint = new Paint();
public void draw(Canvas canvas) {
// draw content here
...
//and mask bitmap here
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));
canvas.drawBitmap(maskBitmap, 0, 0, paint);
}
结果如我所料(内容仅在红色区域可见,但透明区域成为黑色是问题!)
这个图像结果:https://www.dropbox.com/s/mqj48992wllfkiq/s_2%20copy.png任何人帮助我???
这是一个帮助我实现屏蔽的解决方案:
public void draw(Canvas canvas) {
Bitmap original = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.original_image);
Bitmap mask = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.mask_image);
//You can change original image here and draw anything you want to be masked on it.
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas tempCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
tempCanvas.drawBitmap(original, 0, 0, null);
tempCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
//Draw result after performing masking
canvas.drawBitmap(result, 0, 0, new Paint());
}
面具应该是具有透明度的白色图像。 它会像这样工作: + =
我在自定义视图中遇到了同样的问题,而不是从资源中解码位图,我通过canvas.draw*()
方法从头开始创建原始位图和掩蔽位图(因为原始和掩码都是基本形状)。我得到了blank opaque space
而不是transparent
。我通过在我的视图中设置硬件层来修复它。
View.setLayerType(LAYER_TYPE_HARDWARE, paint);
有关为什么要在这里完成的更多信息:https://stackoverflow.com/a/33483016/4747587
Bitmap finalMasking = stackMaskingProcess(imageBitmap, bitmapMasking);
private Bitmap stackMaskingProcess(Bitmap _originalBitmap, Bitmap _maskingBitmap) {
try {
if (_originalBitmap != null)
{
int intWidth = _originalBitmap.getWidth();
int intHeight = _originalBitmap.getHeight();
resultMaskBitmap = Bitmap.createBitmap(intWidth, intHeight, Bitmap.Config.ARGB_8888);
getMaskBitmap = Bitmap.createScaledBitmap(_maskingBitmap, intWidth, intHeight, true);
Canvas mCanvas = new Canvas(resultMaskBitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(_originalBitmap, 0, 0, null);
mCanvas.drawBitmap(getMaskBitmap, 0, 0, paint);
paint.setXfermode(null);
paint.setStyle(Paint.Style.STROKE);
}
} catch (OutOfMemoryError o) {
o.printStackTrace();
}
return resultMaskBitmap;
}
我喜欢Er. Praful Parmar's回答的方法,但对我而言,它并没有像预期的那样工作。我遇到了问题,因为有些扩展是无意的。 我的位图的密度与我的设备不同,这让事情变得混乱。
此外,我想减少对象的创建,因此我将Paint
对象移动到常量以供重用。
所以这是我的utils方法:
public static final//
Bitmap createWithMask(final Bitmap img, final Bitmap mask) {
final Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(),
Bitmap.Config.ARGB_8888);
result.setDensity(originalBitmap.getDensity()); // to avoid scaling if density of 'img' is different form the default on your device
final Canvas canvas = new Canvas(result);
canvas.drawBitmap(img, 0, 0, null);
canvas.drawBitmap(mask, 0, 0, PAINT_FOR_MASK);
return result;
}//end-method
private static final Paint PAINT_FOR_MASK = createPaintForMask();
private static final//
Paint createPaintForMask() {
final Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
return paint;
}//end-method