Skip to content

Instantly share code, notes, and snippets.

@justasm
Created September 1, 2014 17:14
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save justasm/d5c6e04da79866dcd3b8 to your computer and use it in GitHub Desktop.
Save justasm/d5c6e04da79866dcd3b8 to your computer and use it in GitHub Desktop.
Android image compositing - masking Bitmap with another Bitmap.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/** Note - this simple implementation only works with Bitmaps. */
public class MaskImageView extends ImageView {
// A shader that we will use to draw the masked image.
private BitmapShader shader;
// The paint to which we'll apply the shader.
private Paint paint;
// The alpha-only Bitmap to be used as the mask.
private Bitmap mask;
public MaskImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// create the BitmapShader, pointing it to the bitmap of the image this ImageView started with
shader = new BitmapShader(((BitmapDrawable)getDrawable()).getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
// create our paint and attach the shader to it
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
paint.setStyle(Paint.Style.FILL);
}
@Override
public void setImageBitmap(Bitmap bm){
super.setImageBitmap(bm);
// update our shader
shader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
}
/** Provide a Bitmap to mask this view's image. Only the alpha component of the mask will be considered. */
public void setImageMask(Bitmap maskBitmap){
this.mask = convertToAlphaMask(maskBitmap);
}
/**
* BitmapShader works with {@link Canvas#drawBitmap(Bitmap, float, float, Paint)} only if the drawn bitmap
* is purely alpha; to guarantee this, we convert the provided mask ourselves.
*/
private static Bitmap convertToAlphaMask(Bitmap mask){
Bitmap alphaMask = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(alphaMask);
canvas.drawBitmap(mask, 0.0f, 0.0f, null);
return alphaMask;
}
@Override
public void onDraw(Canvas canvas){
// draw our mask, using our image as the shader
if(null != mask) canvas.drawBitmap(mask, 0, 0, paint);
else super.onDraw(canvas);
}
}
@helinwang
Copy link

the gotcha here is you actually draw on the mask with bitmap in BitmapShader of paint. Not the other way around: canvas.drawBitmap(mask, 0, 0, paint);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment