Android drawBitmap的性能差异达到5倍

10

我整晚都在处理Android性能问题,可能解决了一直困扰我的问题,但我仍然很困惑,需要帮助。请考虑这两个样本之间的时间差异。

第一个样本加载可绘制位图并创建其可变副本。

Bitmap cacheBitmap;
Canvas cacheCanvas;
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (cacheBitmap != null) {
        cacheBitmap.recycle();
    }
    Resources res = getContext().getResources();
    Bitmap blankImage = BitmapFactory.decodeResource(res, R.drawable.blank);

    /* copy existing bitmap */
    cacheBitmap = Bitmap.createScaledBitmap(blankImage, w, h, false);
    /* copy existing bitmap */

    cacheCanvas = new Canvas();
    cacheCanvas.setBitmap(cacheBitmap);
    cacheCanvas.drawRGB(255, 255, 255);
}
public void onDraw(Canvas canvas) {
    canvas.drawBitmap(cacheBitmap, 0, 0, null); // draws in 7-8 ms
}
第二个示例创建了一个新的位图,而不是复制原始的空白图像。
Bitmap cacheBitmap;
Canvas cacheCanvas;
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (cacheBitmap != null) {
        cacheBitmap.recycle();
    }
    Resources res = getContext().getResources();
    Bitmap blankImage = BitmapFactory.decodeResource(res, R.drawable.blank);

    /* create fresh bitmap */
    cacheBitmap = Bitmap.createBitmap(w, h, blankImage.getConfig());
    /* create fresh bitmap */

    cacheCanvas = new Canvas();
    cacheCanvas.setBitmap(cacheBitmap);
    cacheCanvas.drawRGB(255, 255, 255);
}
public void onDraw(Canvas canvas) {
    canvas.drawBitmap(cacheBitmap, 0, 0, null); // draws in 40 ms
}
第一个示例比第二个示例绘制得快5-6倍,为什么会这样?我希望能以某种方式编写此代码,即使没有空白图像可用于初始复制,也不必依赖它,但无论我做什么,最终都会得到慢的位图绘制。
2个回答

3

检查位图的格式。在旧版本的Android中,存在一个bug(或者说是特性),当使用某些函数创建位图时,没有alpha通道的位图总是使用565,而有alpha通道的位图总是使用8888。

我倾向于认为某个版本使用8888,而另一个版本使用565,从而使你获得了速度提升。

使用getConfig来调查两个位图。


问题在于,当我调用cacheBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565)时,我的绘制调用需要30毫秒,而当我使用cacheBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)时,我的绘制调用需要40毫秒,所以不仅仅是这个原因。 - seanalltogether
@Romain: 我知道 :) 我密切关注了那个漏洞。听到你谈论Android有点有趣,自从我在Google+上关注你以来,感觉你整天都在旅游拍照 :) - EboMike
@Romain:好的,我在这里有点抢线程了。根据这里的第一条评论,问题似乎不仅仅是565/8888。由于您是Android渲染方面的专家,您有任何想法是从哪里引起的性能差异吗?@seanalltogether:当您尝试第一个代码片段时,getConfig返回什么? - EboMike
听起来非常像是配置问题。 - Romain Guy

1

难道createScaledBitmap()实际上不是创建一个新的位图,其比例恰好适合屏幕,内部进行1:1像素绘制,并可能允许更快的绘制例程,而第二个则只创建一个包含原始资源所有信息(可能有很多额外像素)的新位图,每次调用绘制位图都会在内部位图像素和正在绘制到的画布之间进行内部缩放?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接