Artefatto da ombreggiatura sotto una vigilanza di immagini con un PNG che ha uno sfondo completamente trasparente
-
28-10-2019 - |
Domanda
Sto lavorando su un dispositivo di pan di zenzero (2.3.3). Ho una vigilanza di immagini che contiene una figura di freccia e ha uno sfondo completamente trasparente che devo disegnare su un po 'di sfondo. Il problema è che c'è un artefatto "ombreggiatore" sotto la scatola di delimitazione di ImageView.
Se guardi da vicino la seguente immagine, vedrai l'artefatto di cui sto parlando: 1
Sia l'immagine in primo piano che l'immagine di sfondo hanno canali alfa e quindi sono decodificati come Argb8888 (ho ricontrollato a doppia questo decodificando le loro risorse in una bitmap, stampano la configurazione bitmap che mostrava Argb8888 e quindi assegnandole alle rispettive viste). Ho anche configurato la finestra di Activatiy per essere pixelFormat.rgba_8888 prima della chiamata a setContentView ().
Per favore, non fare riferimento a thread che suggeriscono la decodifica della bitmap come argb8888 e/o impostare la finestra su RGBA_8888, poiché ho provato entrambe le soluzioni, il che non ha aiutato.
Qualche idea su come risolvere questo problema?
MODIFICARE:
Ecco la funzione che imposta il formato pixel della finestra e i drawable (chiamato direttamente da oncreate ()):
public void testTransparency() { getWindow().setFormat(PixelFormat.RGBA_8888); setContentView(R.layout.transparency_test); LinearLayout ll = (LinearLayout)findViewById(R.id.ll); Bitmap bgBmp = BitmapFactory.decodeResource(getResources(), R.raw.bg); Log.d(TAG,"BG BMP Config: " + bgBmp.getConfig()); ll.setBackgroundDrawable(new BitmapDrawable(bgBmp)); ImageView iv = (ImageView)findViewById(R.id.iv); iv.setBackgroundDrawable(null); Bitmap arrowBmp = BitmapFactory.decodeResource(getResources(), R.raw.big_arrow); Log.d(TAG,"Arrow BMP Config: " + arrowBmp.getConfig()); iv.setImageBitmap(arrowBmp); }
Ed ecco il layout (molto semplice) che il mio test sta usando:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView android:id="@+id/iv"
android:layout_width="72dp"
android:layout_height="120dp"
/></LinearLayout>
La risorsa "BG" può essere trovata a 2
La risorsa "Big_arrow" è disponibile su "http://i.imgur.com/3v6qu.png"
EDIT 2:
Ho scoperto che non riesco a riprodurre il problema sull'emulatore, né sul mio N1 (2.3.4) o Xoom (3.2.1). Ci sono 2 opzioni che continuano da qui:
1. Il problema è specifico del dispositivo (Appliance basato su Android che sto lavorando)
2. Esiste un problema specifico con il frameBuffer 2.3.4 e 32bpp mentre si rendono i PNG trasparenti uno sopra l'altro.
Grazie.
Soluzione
Ho trovato il bug e in effetti era un bug specifico della piattaforma.
L'ho scoperto quando rimuovo le ottimizzazioni al neon nella porzione di blit di skia mista (in skblitrow_d32.cpp - Skblitrow :: Proc32 Skblitrow :: Factory32 (bandiere non firmate)), l'artefatto dell'ombreggiatura scompare.
Un consiglio utile per chiunque voglia eseguire il debug di questo tipo di bug:
Puoi sempre disegnare la tua gerarchia di visualizzazione in una bitmap (vedi: Android ottieni una bitmap di una vista prima di disegnare? per esempio) e quindi utilizzare Bitmap.compress Metodo per esportare la bitmap in un file PNG. In questo modo è possibile ottenere la tua snapshot della gerarchia di visualizzazione con il suo canale Alpha (che non appare in uno screenshot DDMS da quando è generato dopo la composizione). Ho scoperto in questo modo che il valore alfa all'interno dell'area ombreggiata è "1" invece di "0", creando l'artefatto.
Altri suggerimenti
Semplicemente impostazione
BackButton.setBackgroundColor(Color.TRANSPARENT);
Risolto il mio problema con un ImageButton su un HTC Desire HD con Android 2.3.5 in cui l'immagine del mio pulsante ha meno altezza dello sfondo predefinito. Osservazione empirica; Artefact non si è mostrato su una Galaxy Note 1 con Android 4.1.2