申请阿尔法为JPEG在一个Android应用程序更快的方法?阿尔法、更快、应用程序、方法

2023-09-06 15:39:34 作者:素衣白裙清浅笑﹋

我使用PNG文件,需要阿尔法对象开始了我的Andr​​oid应用程序,但我很快就意识到,所需的空间实在是太大了。所以,我写了一PNG阿尔法,创造了B和程序; W-- Alpha遮罩png文件和JPEG。这给了我空间节省了大量的,但速度不是很大。

以下是我的Andr​​oid应用程序的code它结合了JPG图像(origImgId在code)和PNG掩码(该alphaImgId在code)。

它的工作原理,但它不是快。我已经缓存结果和我的工作code在比赛开始前将加载在菜单屏幕这些图像,但如果有一种方法,以加快这将是很好的。

有没有人有什么建议?请注意,我修改了code略,使之易于理解。在游戏中其实这是它加载需求的形象和缓存结果的精灵。在这里,你只看到code为加载图像和应用阿尔法。

 公共类BitmapDrawableAlpha{    公共BitmapDrawableAlpha(INT origImgId,诠释alphaImgId){        this.origImgId = origImgId;        this.alphaImgId = alphaImgId;    }    保护BitmapDrawable loadDrawable(活动){        可绘制D = a.getResources()getDrawable(origImgId)。        可绘制DA = a.getResources()getDrawable(alphaImgId)。        位图B = Bitmap.createBitmap(d.getIntrinsicWidth(),d.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);        {            帆布C =新的Canvas(B);            d.setBounds(0,0,d.getIntrinsicWidth() -  1,d.getIntrinsicHeight() -  1);            d.draw(C);        }        位图BA = Bitmap.createBitmap(d.getIntrinsicWidth(),d.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);        {            帆布C =新的Canvas(BA);            da.setBounds(0,0,d.getIntrinsicWidth() -  1,d.getIntrinsicHeight() -  1);            da.draw(C);        }        applyAlpha(2B,BA);        返回新BitmapDrawable(B);    }    / **应用阿尔法到指定的位图湾* /    公共静态无效applyAlpha(位图B,位图bAlpha){        INT W = b.getWidth();        INT H = b.getHeight();        对于(INT Y = 0; Y< H ++ Y){            为(中间体X = 0; X&下;瓦; ++ x)的{                INT像素= b.getPixel(X,Y);                INT finalPixel = Color.argb(Color.alpha(bAlpha.getPixel(X,Y)),Color.red(象素),Color.green(象素),Color.blue(像素));                b.setPixel(X,Y,finalPixel);            }        }    }    私人诠释origImgId;    私人诠释alphaImgId;} 

解决方案

如果你打算每多个像素,你可以叫的getPixels()和的setPixels()让他们的一次。这将美元的闭环P $ pvent附加的方法调用和内存的引用。

Android Q又改进了哪些

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

 公共静态无效applyAlpha(位图B,位图bAlpha){    INT W = b.getWidth();    INT H = b.getHeight();    INT [] = colorPixels新INT [W * H]。    INT [] = alphaPixels新INT [W * H]。    b.getPixels(colorPixels,0,W,0,0,W,H);    bAlpha.getPixels(alphaPixels,0,W,0,0,W,H);    对于(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()与getPixel( )你可以获取alpha位图与 BitmapFactory.de codeResource():

 位图BA = BitmapFactory.de codeResource(a.getResources(),alphaImgId); 

I started my android app using png files for objects that required alpha, but I quickly realized that the space required was simply too much. So, I wrote a program that took a png with alpha and created a b&w alpha mask png file and a jpeg. This gives me a tremendous amount of space savings, but the speed is not great.

The following is the code in my Android app which combines the jpg image (the origImgId in the code) and the png mask (the alphaImgId in the code).

It works, but it's not fast. I already cache the result and I'm working on code which will load these images in the menu screen before the game starts, but it would be nice if there was a way to speed this up.

Does anyone have any suggestions? Note that I modified the code slightly so as to make it easily understandable. In the game this is actually a sprite which loads the image on demand and caches the result. Here you just see the code for loading the images and applying the 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;
}

解决方案

If you are going to be manipulating every multiple pixels you could call getPixels() and setPixels() to get them all at once. This will prevent additional method calls and memory references in your loop.

Another thing you could do is do the pixel addition with bitwise or instead of the helper methods. Preventing method calls should increase efficiency:

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

That being said the process you are trying to undertake is fairly simple, I can't imagine these will provide a huge performance boost. From this point the only suggestion I can provide would be to goto a native implementation with the NDK.

EDIT: Also since a Bitmap doesn't have to be mutable to use getPixels() or getPixel() you can get the alpha bitmap with BitmapFactory.decodeResource():

Bitmap ba = BitmapFactory.decodeResource(a.getResources(), alphaImgId);