开发者

How to combine two opaque bitmaps into one with alpha channel?

I have a PNG file with transparency that I'm using as OpenGL texture. I load it in Bitmap with BitmapFactory.decodeResource, then upload it to GPU.

The PNG file is quite big and in order to cut down on APK size, I'm trying to use two JPGs instead--one with RGB data, and the other with alpha channel (grayscale).

How do I combine the two JPGs together in one B开发者_JS百科itmap object with alpha channel? I tried loading alpha channel as Bitmap.Config.ALPHA_8, then drawing them on top of each other using Canvas but no luck so far.


Have a look at Kevin Dion's answer to this related question. He explains how to combine 4 separate images (R, G, B and A channels) but you should be able to adapt it to work with two images.


Here's a complete example:

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;

public class ImageOps {

    private static final ColorMatrix sRedToAlphaMatrix = new ColorMatrix(new float[] {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        1, 0, 0, 0, 0});

    private static final ColorMatrixColorFilter sRedToAlphaFilter = new ColorMatrixColorFilter(sRedToAlphaMatrix);

    public static Bitmap composeAlpha(Bitmap target, Resources resources, int rgbDrawableId, int alphaDrawableId) {
        final BitmapFactory.Options options = new BitmapFactory.Options();          
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.inScaled = false;       

        // Load RGB data
        Bitmap rgb = BitmapFactory.decodeResource(resources, rgbDrawableId, options);

        if (target == null) {
            // Prepare result Bitmap
            target = Bitmap.createBitmap(rgb.getWidth(), rgb.getHeight(), Bitmap.Config.ARGB_8888);
        }
        Canvas c = new Canvas(target);
        c.setDensity(Bitmap.DENSITY_NONE);

        // Draw RGB data on our result bitmap
        c.drawBitmap(rgb, 0, 0, null);

        // At this point, we don't need rgb data any more: discard!
        rgb.recycle();
        rgb = null;

        // Load Alpha data
        Bitmap alpha = BitmapFactory.decodeResource(resources, alphaDrawableId, options);

        // Draw alpha data on our result bitmap
        final Paint grayToAlpha = new Paint();
        grayToAlpha.setColorFilter(sRedToAlphaFilter);
        grayToAlpha.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        c.drawBitmap(alpha, 0, 0, grayToAlpha); 

        // Don't need alpha data any more: discard!
        alpha.recycle();
        alpha = null;

        return target;
    }

}


Try the following: Iterate through width * height of your two images, and use Bitmap.getPixel(x,y) on each one.

int alpha = Color.red(grayscaleBitmap.getPixel(x, y)); // grayscale, so any color will do
int red = Color.red(colorBitmap.getPixel(x, y));
int green = Color.green(colorBitmap.getPixel(x, y));
int blue = Color.blue(colorBitmap.getPixel(x, y));
int mergedColor = Color.argb(alpha, red, green, blue);
// save mergedColor in an int[]

Then use Bitmap.createBitmap(int[] colors, int width, int height, Bitmap.Config config) to create your new bitmap.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜