Search code examples
javaandroidbitmappaintcolor-channel

Android Edit Bitmap Channels


It's possible to access the alpha channel of a given bitmap with extractAlpha(), but I haven't been able to find any way to actually set the alpha channel of a bitmap.

How can multiple greyscale images be recombined as channels into a Bitmap with Android?


Solution

  • It is quite possible to re-combine separate channels back into an ARGB image. You just need the grayscale channel images and an image with the alpha channel you want - note that this is not an opaque grayscale image, but an image with the alpha you want. You then draw each channel with a Paint using the appropriate PorterDuffXfermode onto a blank, black-filled Bitmap.

    // have your 3 channel grayscales and 1 alpha bitmap loaded by this point
    
    Paint redPaint = new Paint();
    redPaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
    redPaint.setShader(new BitmapShader(redChanImg, TileMode.CLAMP, TileMode.CLAMP));
    redPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, Mode.DARKEN));
    
    Paint greenPaint = new Paint();
    greenPaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
    greenPaint.setShader(new BitmapShader(greenChanImg, TileMode.CLAMP, TileMode.CLAMP));
    greenPaint.setColorFilter(new PorterDuffColorFilter(Color.GREEN, Mode.DARKEN));
    
    Paint bluePaint = new Paint();
    bluePaint.setXfermode(new PorterDuffXfermode(Mode.LIGHTEN));
    bluePaint.setShader(new BitmapShader(blueChanImg, TileMode.CLAMP, TileMode.CLAMP));
    bluePaint.setColorFilter(new PorterDuffColorFilter(Color.BLUE, Mode.DARKEN));
    
    Paint alphaPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    alphaPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
    
    c.setBitmap(resultImage);
    c.drawRect(0, 0, width, height, redPaint);
    c.drawRect(0, 0, width, height, greenPaint);
    c.drawRect(0, 0, width, height, bluePaint);
    c.drawBitmap(alphaImg, 0, 0, alphaPaint);
    
    //save off resultImage, display it, etc...
    

    With the above code and the following 4 images (red, green, blue, and alpha, respectively): alt textalt textalt textalt text

    We get the following result:


    alt text


    Just a quick note: the red oval is an opaque, red oval on a transparent background - the color doesn't matter for this one, but the alpha does