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

前端 未结 3 1659
栀梦
栀梦 2021-01-22 03:29

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.

相关标签:
3条回答
  • 2021-01-22 03:37

    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;
        }
    
    }
    
    0 讨论(0)
  • 2021-01-22 03:46

    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 讨论(0)
  • 2021-01-22 03:54

    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.

    0 讨论(0)
提交回复
热议问题