1

我使用 png 文件为需要 alpha 的对象启动了我的 android 应用程序,但我很快意识到所需的空间实在是太多了。因此,我编写了一个程序,该程序采用带有 alpha 的 png 并创建了一个 b&w alpha mask png 文件和一个 jpeg。这给了我大量的空间节省,但速度不是很好。

以下是我的 Android 应用程序中的代码,它结合了 jpg 图像(代码中的 origImgId)和 png 掩码(代码中的 alphaImgId)。

它有效,但速度不快。我已经缓存了结果,并且正在编写代码,该代码将在游戏开始之前将这些图像加载到菜单屏幕中,但如果有一种方法可以加快速度,那就太好了。

有没有人有什么建议?请注意,我稍微修改了代码以使其易于理解。在游戏中,这实际上是一个精灵,它按需加载图像并缓存结果。在这里,您只看到加载图像和应用 alpha 的代码。

public class BitmapDrawableAlpha
{
    public BitmapDrawableAlpha(int origImgId, int alphaImgId) {
        this.origImgId = origImgId;
        this.alphaImgId = alphaImgId;
    }

    protected BitmapDrawable loadDrawable(Activity a) {
        Drawable d = a.getResources().getDrawable(origImgId);
        Drawable da = a.getResources().getDrawable(alphaImgId);

        Bitmap b = Bitmap.createBitmap(d.getIntrinsicWidth(),d.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);
        {
            Canvas c = new Canvas(b);
            d.setBounds(0,0,d.getIntrinsicWidth()-1,d.getIntrinsicHeight()-1);
            d.draw(c);
        }

        Bitmap ba = Bitmap.createBitmap(d.getIntrinsicWidth(),d.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);
        {
            Canvas c = new Canvas(ba);
            da.setBounds(0,0,d.getIntrinsicWidth()-1,d.getIntrinsicHeight()-1);
            da.draw(c);
        }

        applyAlpha(b,ba);

        return new BitmapDrawable(b);
    }

    /** Apply alpha to the specified bitmap b. */
    public static void applyAlpha(Bitmap b, Bitmap bAlpha) {
        int w = b.getWidth();
        int h = b.getHeight();
        for(int y=0; y < h; ++y) {
            for(int x=0; x < w; ++x) {
                int pixel = b.getPixel(x,y);
                int finalPixel = Color.argb(Color.alpha(bAlpha.getPixel(x,y)), Color.red(pixel), Color.green(pixel), Color.blue(pixel));
                b.setPixel(x,y,finalPixel);
            }
        }
    }

    private int origImgId;
    private int alphaImgId;
}
4

1 回答 1

2

如果您要处理每个多个像素,您可以调用getPixels()setPixels()来一次获取所有像素。这将防止循环中的其他方法调用和内存引用。

您可以做的另一件事是使用按位或代替辅助方法进行像素加法。防止方法调用应该提高效率:

public static void applyAlpha(Bitmap b, Bitmap bAlpha) {
    int w = b.getWidth();
    int h = b.getHeight();
    int[] colorPixels = new int[w*h];
    int[] alphaPixels = new int[w*h];
    b.getPixels(colorPixels, 0, w, 0, 0, w, h);
    bAlpha.getPixels(alphaPixels, 0, w, 0, 0, w, h);
    for(int j = 0; j < colorPixels.length;j++){
        colorPixels[j] = alphaPixels[j] | (0x00FFFFFF & colorPixels[j]);
    }
    b.setPixels(colorPixels, 0, w, 0, 0, w, h);
}

话虽如此,您尝试执行的过程相当简单,但我无法想象这些将提供巨大的性能提升。从这一点来看,我能提供的唯一建议是使用NDK转到本机实现。

编辑:此外,由于位图不必是可变的,getPixels()或者您可以使用BitmapFactory.decodeResource()getPixel()获取 alpha 位图:

Bitmap ba = BitmapFactory.decodeResource(a.getResources(), alphaImgId);
于 2012-09-02T05:57:56.950 回答