Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用alpha通道将两个不透明位图合并为一个?_Android_Graphics - Fatal编程技术网

Android 如何使用alpha通道将两个不透明位图合并为一个?

Android 如何使用alpha通道将两个不透明位图合并为一个?,android,graphics,Android,Graphics,我有一个透明的PNG文件,我用它作为OpenGL纹理。我用BitmapFactory.decodeResource将其加载到Bitmap中,然后将其上载到GPU PNG文件非常大,为了减少APK大小,我尝试使用两个JPG——一个带有RGB数据,另一个带有alpha通道(灰度) 如何将两个JPG组合在一个带有alpha通道的位图对象中?我尝试将alpha通道加载为位图.Config.alpha_8,然后使用画布将它们绘制在彼此的顶部,但目前为止运气不佳。尝试以下操作:迭代两幅图像的宽度*高度,并在

我有一个透明的PNG文件,我用它作为OpenGL纹理。我用
BitmapFactory.decodeResource
将其加载到
Bitmap
中,然后将其上载到GPU

PNG文件非常大,为了减少APK大小,我尝试使用两个JPG——一个带有RGB数据,另一个带有alpha通道(灰度)


如何将两个JPG组合在一个带有alpha通道的
位图
对象中?
我尝试将alpha通道加载为
位图.Config.alpha_8
,然后使用
画布
将它们绘制在彼此的顶部,但目前为止运气不佳。

尝试以下操作:迭代两幅图像的宽度*高度,并在每个图像上使用Bitmap.getPixel(x,y)

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[]

然后使用Bitmap.createBitmap(int[]颜色、int宽度、int高度、Bitmap.Config配置)创建新位图。

查看。他解释了如何组合4个单独的图像(R、G、B和A通道),但您应该能够调整它以处理两个图像。

以下是一个完整的示例:

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

}

绝对正确。:)廉价的CPU将是PNG。我不知道它比其他任何东西都贵。这确实会让CPU有点窒息。我有一些1024x1024的纹理。我现在对此有点恼火。getPixel应该是O(1),因为它只是一个数组索引方法。双循环仍然是O(n),其中n是像素数。你们真的认为会有比O(n)更好的算法吗?仅仅因为您调用了其他更高级的传输方法,并不意味着您不再遍历像素。我宁愿听到“我试过的时候还不够快”,而不是“我没有试过,但我打赌对我来说太慢了”。对不起,迈卡,我应该检查一下我的假设,毕竟没那么难。因此,在我的NexusOne上,画布方法需要约450ms,1024x1024位图,getPixel方法需要约7000ms。我在某个地方读到过,画布操作有时可以在GPU上执行,也许这是造成如此巨大的速度差异的原因之一。另外,忘了提一下,你建议的逐像素方法要短得多,也更容易理解。因此,它可能非常适合像48x48图标这样的较小图形。啊,我怀念简单位图的日子:)我现在不知道这是否是一个适合你的解决方案。。。有时会将图像缩小60%以上。GreetsHi@Dusty,谢谢你的评论,今天我一定会给tinypng,pngquant这样的机会。将PNG拆分为两个不透明JPG的好处是,我可以单独精确地控制两层的压缩/质量。谢谢,这很有帮助。通过稍微调整一下,我能够从一个RGB位图和一个带有alpha通道的PNG生成我的纹理。我希望alpha通道也存储在JPG中,所以还有一个问题——如何将灰度位图转换为alpha_8位图。发布了一个关于将灰度位图转换为alpha掩码的后续问题:找到了剩余灰度->alpha问题的解决方案: