2014-02-17 8 views
5

Ich habe vor kurzem bemerkt, diese Ausnahmen (die gefangen sind, aber in logcat angemeldet):Neue Warnung in Android 4.4

W/System.err(2612): java.lang.RuntimeException: Canvas: trying to use a non-premultiplied bitmap [email protected] 
W/System.err(2612): at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1088) 
W/System.err(2612): at android.graphics.Canvas.<init>(Canvas.java:139) 
System.err(2612): at com.example.imaging.ImageHelper.addShadow(ImageHelper.java:553) 

Ich habe versucht zu verstehen, was diese Ausnahme Mittel (sowie Nicht-premultiplied Bitmaps) , aber ich bin nicht sicher, was diese Ausnahme verursachen könnte. Ist das Problem mit den Bildern, die wir vom Server bekommen, oder ist es etwas, das wir lokal machen? (Es ist nicht nur diese Zeile, die die Ausnahme verursacht, aber es ist einer von ihnen).

Zum Vergleich habe ich die Methode in Frage hier hinzugefügt und die eine hervorheben, die die Ausnahme verursacht:

public static Bitmap addShadow(Bitmap bitmap) { 
    try { 
     BlurMaskFilter blurFilter = new BlurMaskFilter(12, BlurMaskFilter.Blur.OUTER); 
     Paint shadowPaint = new Paint(); 
     shadowPaint.setMaskFilter(blurFilter); 
     shadowPaint.setShadowLayer(12, -3, -3, Color.parseColor("#33000000")); 
     int[] offsetXY = new int[2]; 

     Bitmap shadowImage = bitmap.extractAlpha(shadowPaint, offsetXY); 
     Bitmap shadowImage32 = shadowImage.copy(Bitmap.Config.ARGB_8888, true); 

     Canvas c = new Canvas(shadowImage32); // exception occurs here <---- 
     c.drawBitmap(bitmap, -offsetXY[0], -offsetXY[1], null); 

     return shadowImage32; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return bitmap; // if error return the original bitmap 

} 
+0

Ich glaube, das hat zu tun mit einem ausgeprägten Alphakanal, gegenüber dem Multiplizieren des Alphas in die Farbkomponenten, um ein Format zu erzeugen, das direkter (und somit effizienter) mit der tatsächlichen Display-Implementierung kompatibel ist. –

+0

@ChrisStratton bedeutet dies, dass ich die Bilder auf dem Server ändern/neu konvertieren sollte oder sollte ich die addShadow-Funktion ändern? – ajacian81

+0

Wenn es für Sie akzeptabel ist, wäre eine Änderung auf dem Server wahrscheinlich die ressourceneffizienteste Lösung. –

Antwort

7

Ich bin mit Blick auf genau das gleiche Problem in dem genau den gleichen Code, aber ich brauche um dies im Android-Code zu lösen, die Bilder nicht außerhalb der App zu ändern, da ich die Bilder benutze, die vom Gerät des Benutzers geladen werden.

Was ich gefunden habe, ist die folgende, kurz vor dem Leinwand Aufruf:

// Fix the non pre-multiplied state. 
if (!shadowImage32.isPremultiplied()) 
{ 
    shadowImage32.setPremultiplied(true); 
} 

Das Problem hier ist, dass meine min API-Ebene 10 ist, und isPremultiplied() API benötigt 17 und setPremultiplied (true) API benötigt 19.

Edit: ich habe getestet, um eine Vorrichtung mit API 10 verwendet und es gibt keine solche Ausnahme, also denke ich, in API 19 sie einführen d Vormultiplikationsbehandlung und Ausnahme. So, endlich, hat mein Code diese Zeilen:

// Fix the non pre-multiplied exception for API 19+. 
if (android.os.Build.VERSION.SDK_INT >= 19 && !shadowImage32.isPremultiplied()) 
{ 
    shadowImage32.setPremultiplied(true); 
} 
3

zu Xavi Antwort Bezug, mit einem sehr alten Code, den ich diese Methode aufgerufen (neues Gerät unterstützt) mit Reflexion:

if (android.os.Build.VERSION.SDK_INT >= 19) 
      { 
       try { 
        java.lang.reflect.Method method = shadowImage32.getClass().getMethod("setPremultiplied",boolean.class); 
        method.invoke(shadowImage32, true); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
Verwandte Themen