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

喜欢而已 提交于 2019-12-31 02:46:25

问题


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 Bitmap 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.


回答1:


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.




回答2:


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;
    }

}



回答3:


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.



来源:https://stackoverflow.com/questions/5098680/how-to-combine-two-opaque-bitmaps-into-one-with-alpha-channel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!