2011-08-09 12 views
10

Walczyłem z Androidem przez całą noc i prawdopodobnie rozwiązałem problem, z którym miałem do czynienia, jednak nadal jestem bardzo zdezorientowany i mogę skorzystać z pomocy. Rozważ różnice czasowe między tymi dwiema próbkami.Android drawBitmap 5x różnica wydajności

Pierwsze ładunki próbki w rozciągliwej bitmapy i tworzy zmienny kopię

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 
} 

Druga próbka tworzy nową bitmapę bez kopiowania oryginalnego pustego obrazu.

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 
} 

Pierwsza próbka rysuje 5-6 razy szybciej niż druga próbka, dlaczego tak jest? Chciałbym móc napisać ten kod w pewien sposób, który nie opiera się nawet na pustym obrazie, ale bez względu na to, co robię, kończę z wolnym rysowaniem bitmapowym bez możliwości wcześniejszego skopiowania.

Odpowiedz

3

Sprawdź format mapy bitowej. W starszych wersjach Androida był błąd (funkcja?), Który zawsze używał 565 dla bitmap bez alfa i 8888 dla bitmap z alfa podczas tworzenia bitmapy przy użyciu pewnych funkcji.

Mam ochotę powiedzieć, że jakoś jedna wersja używa 8888, podczas gdy druga używa 565, dając przyrost prędkości.

Skorzystaj z getConfig, aby zbadać obie bitmapy.

+0

Chodzi o to, gdy zgłoszę cacheBitmap = Bitmap.createBitmap (w, h, Bitmap.Config.RGB_565) moje rozmowy remis po 30 ms i kiedy używać cacheBitmap = Bitmap.createBitmap (w, h, bitmapy. Config.ARGB_8888) moje wywołania remisowe trwają 40 ms, więc to nie tylko to. – seanalltogether

+7

To była funkcja :) –

+0

@Romain: Wiem :) Dokładnie podążałem za tym błędem. Miło słyszeć, że rozmawiasz o Androidzie, odkąd zacząłem Cię śledzić w Google+, masz wrażenie, że spędzasz cały dzień podróżując po świecie i robiąc zdjęcia :) – EboMike

1

Nie może być tak, że faktycznie tworzy nową bitmapę z dokładnie proporcjami wymaganymi dla ekranu, dając wewnętrzny pik 1: 1 i prawdopodobnie pozwalając na szybszą procedurę rysowania, gdzie druga tworzy nową bitmapa, która zawiera WSZYSTKIE informacje dla oryginalnego zasobu (prawdopodobnie wiele dodatkowych pikseli), a każde wywołanie do narysowania mapy bitowej powoduje wewnętrzne skalowanie pomiędzy pikselami w wewnętrznej bitmapie i rysowanym płótnie?

Powiązane problemy