Android Mask bitmap on canvas gen a black space
Here is a solution which helped me to implement masking:
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());
}
The mask should be a white image with transparency.
It will work like this:
+ =
Android Bitmap Masking (Xfermode) leaves opaque black background behind
It seems that to get the Xfermode
done, I need to redirect the drawing to an offscreen bitmap. So adding the following fixed my problem.
canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), q);
But then again, the documentation of saveLayer
says to avoid using this method since it is expensive. It is suggested to use a harware layer instead of this method.
Avoid using this method, especially if the bounds provided are large,
or if the CLIP_TO_LAYER_SAVE_FLAG is omitted from the saveFlags
parameter. It is recommended to use a hardware layer on a View to
apply an xfermode, color filter, or alpha, as it will perform much
better than this method.
Hence, intead of saveLayer
method, I was able to fix it by adding the following:
setLayerType(LAYER_TYPE_HARDWARE, q);
How to draw on bitmap using another bitmap as mask?
I had to change the masks as described by @Christian. Then, the wanted result could easily be produced:
canvas.drawRect(rect, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawBitmap(mask, 0.0f, 0.0f, paint);
How to Draw a Pattern on Bitmap using canvas
Option 1: Transparent Foreground
If you follow the process described here to merge the two images, you can draw one image onto another. Simply change the opacity of the top-most image as described here. Consider the following example:
Bitmap bitmap = Bitmap.createBitmap(/* width */, /* height */, Config.ARGB_8888);
Paint alpha = new Paint();
alpha.setAlpha(/* alpha */);
Canvas canvas = new Canvas(bitmap);
Bitmap background = BitmapFactory.decodeResource(
getResources(), R.drawable.background);
Bitmap foreground = BitmapFactory.decodeResource(
getResources(), R.drawable.pattern);
canvas.drawBitmap(background, /* xPos */, /* yPos */, null);
canvas.drawBitmap(foreground, /* xPos */, /* yPos */, alpha);
Option 2: Background Masked with Foreground
Alternatively, if you are trying to mask the image, you can consider implementing the solution found here.
Drawing a Bitmap to a Canvas with an alpha gradient
use a ComposeShader
, like this:
class V extends View {
Bitmap bitmap;
Paint paint = new Paint();
public V(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chrome);
Shader shaderA = new LinearGradient(0, 0, bitmap.getWidth(), 0, 0xffffffff, 0x00ffffff, Shader.TileMode.CLAMP);
Shader shaderB = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SRC_IN));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
}
Related Topics
How to Set "Android:Layout_Below" at Runtime Programmatically
Spannablestringbuilder to Create String with Multiple Fonts/Text Sizes etc Example
Findclass from Any Thread in Android Jni
Android N Requires the Ide to Be Running with Java 1.8 or Later
How to Know When the Recyclerview Has Finished Laying Down the Items
How to Show Shadow Around the Linearlayout in Android
Android Camera Intent Saving Image Landscape When Taken Portrait
Android: Why Is There No Maxheight for a View
Android Studio 3.0 Execution Failed for Task: Unable to Merge Dex
Overlay Images Onto Camera Preview Surfaceview
Fragments Destroyed/Recreated with Jetpack's Android Navigation Components
Generate Signed APK Android Studio
Android Split Action Bar with Action Items on the Top and Bottom
Using Android Intent.Action_Send for Sending Email
How to Open Standard Google Map Application from My Application
How to Repeat a Method Every 10 Minutes After a Button Press and End It on Another Button Press