15

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?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
Kleptine
  • 5,089
  • 16
  • 58
  • 81

3 Answers3

24

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

Kevin Dion
  • 4,027
  • 1
  • 17
  • 13
0

Manipulating Bitmaps is a farily simple thing, when to access the pixel (bytes) directly. To do that in Android you can do it over this approch

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); 
byte[] b = bos.toByteArray();  

Now you can do any image manipulation, tranformation or combination you like.

I hope this is what you were looking for.

Endian Ogino
  • 146
  • 3
  • Not quite. I have the Bitmap in a perfectly editable state. I can apply filters, transformations and the like. What I can't figure out is how to edit individual channels, rather than the entire image at once. – Kleptine Jan 05 '11 at 05:55
0

Have you tried with canvas? The following looks like a hack, but maybe it will work. I have not tested it myself.

    Bitmap bitmap;
    int color = bitmap.getPixel(1, 123);
    Rect rect = new Rect(1,123,2,124);
    Canvas c = new Canvas(bitmap);
    c.clipRect(rect);
    c.drawARGB(50, Color.red(color), Color.green(color), Color.blue(color));
Phyrum Tea
  • 2,623
  • 1
  • 19
  • 20
  • or use a buffer and read/write the color directly from/to there bitmap.copyPixelsToBuffer(Buffer dst) – Phyrum Tea Jan 07 '11 at 00:40
  • This would certainly work for simple manipulation, but accessing pixel by pixel is far too slow, since I need this to be done in real time. – Kleptine Jan 07 '11 at 06:20
  • I see, you want to use a greyscaled picture as alpha for other picture. I don't see a ready method. You may have to access the buffer directly and do it on the bit level yourself. – Phyrum Tea Jan 07 '11 at 07:41
  • Have looked in the Android source? There could be a hardware accellerated method doing that. – Phyrum Tea Jan 07 '11 at 07:55