Android – use bitmap as a gradient mask

I have implemented a flood fill algorithm in an android app. The way I have implemented the algorithm doesn’t actually change the source bitmap, but instead creates a new bitmap of the fill area. I.E.

Flood filling this circle with red

circle

Would produce this bitmap (where everything else in the bitmap is transparent)

red

Which I then combine again into a single bitmap. This works great for solid colors, but I want to be able to implement a gradient flood fill so that if a user fills the same circle, choosing red and blue, the resulting bitmap would look like this

redblue

My question is, is there a way that I can use the red circle as some sort of mask to make the desired gradient? or do I have to write a gradient generator myself?

Answer

Thanks to pskink’s hint, I was able to find an answer.

The idea is that you create a canvas, draw the mask to it, create the gradient that you want, then draw the gradient on top of it using the SRC_IN PorterDuffXfermode. Here’s the code:

public Bitmap addGradient(Bitmap src, int color1, int color2)
{
    int w = src.getWidth();
    int h = src.getHeight();
    Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);

    canvas.drawBitmap(src, 0, 0, null);

    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0,0,0,h, color1, color2, Shader.TileMode.CLAMP);
    paint.setShader(shader);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawRect(0,0,w,h,paint);

    return result;
}

In this instance, the DST(destination) is the red circle and the SRC(source) is the gradient. The SRC_IN PorterDuff mode means draw the SRC everywhere that it intersects with the DST.

Note that it really doesn’t matter what color the mask is, because the PorterDuff mode only pays attention to whether the DST pixel is transparent or not. The color of the resulting bitmap will be a gradient between color1 and color2.

Leave a Reply

Your email address will not be published. Required fields are marked *