Android drawBitmap 5x разность производительности

Я всю ночь боролся с работой 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 раз быстрее, чем второй образец, почему это? Я хотел бы иметь возможность написать этот код в некотором роде, который даже не полагается на пустое изображение, но независимо от того, что я делаю, я заканчиваю медленным рисованием растровых изображений, не имея его доступного для первоначального копирования.

Ответ 1

Проверьте формат растрового изображения. В старых версиях Android была ошибка (функция?), Которая всегда использовала бы 565 для растровых изображений без альфа и 8888 для битмапов с альфой при создании растрового изображения с использованием определенных функций.

У меня возникает соблазн сказать, что почему-то одна версия использует 8888, а другая использует 565, что дает вам коэффициент усиления.

Используйте getConfig для исследования обоих растровых изображений.

Ответ 2

Не может ли быть, что createScaledBitmap() фактически создает новую растровую карту с точно пропорциями, необходимыми для экрана, давая внутреннее рисование размером 1:1 и, вероятно, позволяя использовать более быструю процедуру рисования, где вторая просто создает новый битмап, который содержит ВСЕ информацию для исходного ресурса (возможно, много дополнительных пикселей), и каждый вызов для рисования растрового изображения приводит к внутреннему масштабированию между пикселями во внутреннем растровом изображении и холстом, который нарисован на?