2012-02-12 16 views
7

Próbuję załadować mapę ruchu z obrazu PNG. Aby zaoszczędzić pamięć po załadowaniu bitmapy, robię coś takiego.ALPHA_8 bitmapy i getPixel


`Bitmap mapBmp = tempBmp.copy(Bitmap.Config.ALPHA_8, false);` 

Gdybym narysować mapBmp mogę zobaczyć mapę, ale kiedy używam getPixel() otrzymuję zawsze równy 0 (zero).

Czy istnieje sposób na odzyskanie informacji ALPHA z mapy bitowej innej niż za pomocą funkcji getPixel()?

Odpowiedz

0

udało mi się znaleźć ładne i rodzaj czystą drogę do tworzenia map brzegowe. Od początku tworzę mapę bitową ALPHA_8. I pomaluj moją mapę granic ścieżkami. Następnie używam copyPixelsToBuffer() i przesyłam bajty do ByteBuffer. Używam bufora do "getPixels". Myślę, że jest to dobre rozwiązanie, ponieważ można skalować w dół lub w górę ścieżkę() i narysować mapę graniczną o pożądanej rozdzielczości ekranu i bez operacji dekodowania IO +. Bitmap.getPixel() jest bezużyteczny dla bitmap ALPHA_8, to zawsze zwraca 0.

+0

Czy mógłbyś podać przykład, w jaki sposób mogę wyodrębnić "piksele" 'Bitmapy' ALPHA_8'? Zawsze otrzymuję 0 ... –

4

Wydaje się być błędem Androida w obsłudze ALPHA_8. Próbowałem też copyPixelsToBuffer, bezskutecznie. Najprostszym rozwiązaniem jest zmarnowanie dużej ilości pamięci i użycie ARGB_8888.

Issue 25690

1

znalazłem na to pytanie z Google i udało mi się wyodrębnić pikseli przy użyciu metody copyPixelsToBuffer() że Mitrescu Catalin skończyło się. To właśnie mój kod wygląda w przypadku gdy ktoś inny uzna to za dobrze:

public byte[] getPixels(Bitmap b) { 
    int bytes = b.getRowBytes() * b.getHeight(); 
    ByteBuffer buffer = ByteBuffer.allocate(bytes); 
    b.copyPixelsToBuffer(buffer); 
    return buffer.array(); 
} 

Jeśli kodująca poziom API 12 lub wyższy można użyć getByteCount() zamiast uzyskać całkowitą liczbę bajtów przeznaczyć. Jeśli jednak kodujesz poziom API 19 (KitKat), powinieneś zamiast tego użyć getAllocationByteCount().

0

Opracowałem rozwiązanie z biblioteką PNGJ, odczytałem obraz z zasobów, a następnie utworzyłem bitmapę za pomocą Config.ALPHA_8.

import ar.com.hjg.pngj.IImageLine; 
import ar.com.hjg.pngj.ImageLineHelper; 
import ar.com.hjg.pngj.PngReader; 

public Bitmap getAlpha8BitmapFromAssets(String file) { 

    Bitmap result = null; 

    try { 

     PngReader pngr = new PngReader(getAssets().open(file)); 
     int channels = pngr.imgInfo.channels; 
     if (channels < 3 || pngr.imgInfo.bitDepth != 8) 
      throw new RuntimeException("This method is for RGB8/RGBA8 images"); 

     int bytes = pngr.imgInfo.cols * pngr.imgInfo.rows; 
     ByteBuffer buffer = ByteBuffer.allocate(bytes); 

     for (int row = 0; row < pngr.imgInfo.rows; row++) { 

      IImageLine l1 = pngr.readRow(); 

      for (int j = 0; j < pngr.imgInfo.cols; j++) { 

       int original_color = ImageLineHelper.getPixelARGB8(l1, j); 

       byte x = (byte) Color.alpha(original_color); 

       buffer.put(row * pngr.imgInfo.cols + j, x ^= 0xff); 

      } 

     } 

     pngr.end(); 

     result = Bitmap.createBitmap(pngr.imgInfo.cols,pngr.imgInfo.rows, Bitmap.Config.ALPHA_8); 
     result.copyPixelsFromBuffer(buffer); 

    } catch (IOException e) { 
     Log.e(LOG_TAG, e.getMessage()); 
    } 

    return result; 

} 

Również odwracam wartości alfa ze względu na moje szczególne potrzeby. Ten kod jest testowany tylko pod kątem interfejsu API 21.