Pytanie Android: ładowanie bitmapy z maską alfa


Mam jednokanałowy plik PNG, który chciałbym użyć jako maski alfa do operacji rysowania Porter-Duff. Jeśli załaduję go bez żadnych opcji, wynikowa mapa bitowa ma konfigurację RGB_565, czyli jest traktowana jako skala szarości. Jeśli ustawię preferowaną konfigurację na ALPHA_8, ładuję ją zamiast ARGB_8888 w skali szarości.

Jak mogę przekonać Androida do traktowania tego pliku jako maski alpha zamiast obrazu w skali szarości?

mask1 = BitmapFactory.decodeStream(pngStream);
// mask1.getConfig() is now RGB_565

BitmapFactory.Options maskOpts = new BitmapFactory.Options();
maskOpts.inPreferredConfig = Bitmap.Config.ALPHA_8;
mask2 = BitmapFactory.decodeStream(pngStream, null, maskOpts);
// mask2.getConfig() is now ARGB_8888 (the alpha channel is fully opaque)

12
2017-10-28 19:12


pochodzenie


Co się stanie, gdy ustawisz preferowaną konfigurację na ARGB_8888? - EboMike
Ten sam wynik co ALPHA_8. Otrzymuję mapę bitową ARGB_8888 z nieprzezroczystym kanałem alfa. - kvance
Jakiego rodzaju jest twój png? Zgaduję 0, czyli w skali szarości. O ile mi wiadomo, nie ma pliku png "alpha only". Najbliżej można było uzyskać paletę 8-bitową z mapą identyczności indeksu do alfa - dla rozmiaru pliku. Ale prawdopodobnie nie warto. Twoje obejście poniżej jest prawdopodobnie najlepszym rozwiązaniem. Ale nie znoszę być tym facetem: API próbuje ci coś tutaj powiedzieć! Trzymaj alfa i RGB razem. Zawsze. Będzie szybszy i lepiej obsługiwany. Za pomocą ALPHA_8 pozostawiasz dobrą ścieżkę. Spróbuj zmienić swój projekt na RGBA, jeśli to w ogóle możliwe. - starmole
@starmole Prawidłowo, był to PNG w skali szarości. W tym konkretnym przypadku miałem duże, animowane duszki z kanałem alfa. Pod względem wielkości aplikacji warto było skompresować dane RGB przy pomocy JPEG i kanału alfa z PNG. - kvance


Odpowiedzi:


Więcej obejścia niż rozwiązanie:

Teraz włączam kanał alfa do pliku RGBA PNG, a wszystkie kanały RGB zerują. Mogę załadować ten plik z preferowaną konfiguracją ARGB_8888, a następnie wyodrębnić jego kanał alfa. Powoduje to marnowanie kilku kilobajtów w pliku maski i dużo pamięci podczas dekodowania obrazu.

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap source = BitmapFactory.decodeStream(pngStream, null, opts);
Bitmap mask = source.extractAlpha();
source.recycle();
// mask.getConfig() is now ALPHA_8

6
2017-10-29 15:11



Czy kiedykolwiek znalazłeś lepsze rozwiązanie? Występuję w tym samym problemie. - Tenfour04
@ TenFour04 Nigdy niestety nie. - kvance