1

アルファが必要なオブジェクトのpngファイルを使用してAndroidアプリを起動しましたが、必要なスペースが多すぎることにすぐに気付きました。そこで、アルファ付きのpngを取り、白黒アルファマスクのpngファイルとjpegを作成するプログラムを作成しました。これにより、スペースを大幅に節約できますが、速度はそれほど速くありません。

以下は、jpg画像(コード内のorigImgId)とpngマスク(コード内のalphaImgId)を組み合わせたAndroidアプリのコードです。

動作しますが、高速ではありません。私はすでに結果をキャッシュしていて、ゲームが始まる前にメニュー画面にこれらの画像をロードするコードに取り組んでいますが、これを高速化する方法があればいいのですが。

誰か提案はありますか?わかりやすくするために、コードを少し変更したことに注意してください。ゲームでは、これは実際にはオンデマンドで画像をロードし、結果をキャッシュするスプライトです。ここに、画像をロードしてアルファを適用するためのコードが表示されます。

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()を呼び出して、それらすべてを一度に取得できます。これにより、ループ内での追加のメソッド呼び出しとメモリ参照が防止されます。

もう1つできることは、ビット単位またはヘルパーメソッドの代わりにピクセルの追加を行うことです。メソッド呼び出しを防ぐと、効率が向上します。

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()を使用してアルファビットマップを取得できます:

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