Unveränderlicher Bitmap-Absturzfehler

73
java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
at android.graphics.Canvas.<init>(Canvas.java:127)
at app.test.canvas.StartActivity.applyFrame(StartActivity.java:214)
at app.test.canvas.StartActivity$1.onClick(StartActivity.java:163)
at android.view.View.performClick(View.java:4223)
at android.view.View$PerformClick.run(View.java:17275)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)

Ich erhalte diesen Absturzfehler von der Entwicklerkonsole. Ich verstehe nicht, wo das Problem liegt.

    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inScaled = true;
    opt.inPurgeable = true;
    opt.inInputShareable = true;
    Bitmap brightBitmap = BitmapFactory.decodeResource(getResources(), position, opt); 
    brightBitmap = Bitmap.createScaledBitmap(brightBitmap, 550, 550, false);
    chosenFrame = brightBitmap;
    Bitmap workingBitmap = Bitmap.createBitmap(chosenFrame);
    workingBitmap = Bitmap.createBitmap(workingBitmap); 
    Canvas c = new Canvas(workingBitmap);

Ich denke, es hängt damit zusammen?

Yerry Huntry
quelle

Antworten:

207

Sie müssen Ihre workingBitmapin konvertieren , Mutable Bitmapum darauf zu zeichnen Canvas. (Hinweis: Diese Methode hilft nicht, Speicher zu sparen, sie benötigt zusätzlichen Speicher.)

Bitmap workingBitmap = Bitmap.createBitmap(chosenFrame);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);

Diese Antwort hilft, keinen Speicher zu verschwenden. Konvertieren Sie unveränderliche Bitmap in eine veränderbare Bitmap

Dimetil
quelle
Diese Methode hilft, Speicherplatz zu sparen. Ich habe die Antwort mit der einfachsten Methode bearbeitet, um eine veränderbare Bitmap zu
erstellen
Wenn ich die Methode verwende, stürzt die App ab und im Logcat heißt es, dass Canvas keine recycelte Bitmap verwenden kann
Yerry Huntry
Also benutze ich deine Methode ohne die Antwort im Link?
Yerry Huntry
2
@dimetil Wie verschwendet es keinen Speicher? Es erstellt tatsächlich eine völlig identische neue Bitmap, so dass Sie 2-mal mehr Speicher auf dieser Bitmap verwenden ...
Android-Entwickler
Hier ist eine Methode, die Speicher spart, die ich erstellt habe: stackoverflow.com/a/16314940/878126
Android-Entwickler
39

BitmapFactory.decodeResource()Gibt eine unveränderliche Kopie der Bitmap zurück und Sie können nicht auf die Zeichenfläche zeichnen. Um die Zeichenfläche zu erhalten, benötigen Sie eine veränderbare Kopie der Bitmap der Bilder. Dies kann durch Hinzufügen eines einzeiligen Codes erfolgen.

opt.inMutable = true;

Fügen Sie diese Zeile Ihrem Code hinzu und sie sollte den Absturz beheben.

codeFood
quelle
2
Dies sollte die Antwort sein, da es keinen Speicher verbraucht, was bei Verwendung von bitmap.copy (...) der Fall ist
Java
Es ist wichtig, die Bitmap-Eigenschaften zu überprüfen und festzulegen, bevor Bitmap in den Speicher geladen wird. Verwenden Sie diese Antwort, wenn Speicher ein Problem darstellt, insbesondere wenn Sie eine Bitmap mit großen Dimensionen verwenden.
Thracian
3

Das funktioniert auch, ich habe es gerade getestet.

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
return BitmapFactory.decodeByteArray(resultDecoded, 0, resultDecoded.length,options);
Joe
quelle
2

Sofern Sie Ihre IMMUTABLE-Bitmap nicht in MUTABLE-Bitmap umwandeln möchten, können Sie Speicher sparen, indem Sie die BITMAP IMMER WIEDER VERWENDEN

workingBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(workingBitmap);

Ich denke jedoch, dass dies dasselbe sein kann, als würde man die Bitmap durch Aufrufen veränderbar machen

workingBitmap.isMutable = true
Ujju
quelle
1
Es gibt keine Variable namens "isMutable" in der Bitmap
Amr Ashraf