it-swarm.com.de

Android: Bitmap zu Byte Array und zurück: SkImageDecoder :: Factory hat null zurückgegeben

Das Ziel besteht darin, eine Bitmap in einen byte [] zu konvertieren, sie zwischen Aktivitäten in einer Bundle von Daten zu übergeben und sie zu einem späteren Zeitpunkt wieder in eine Bitmap für die Anzeige in einer Imageview umzuwandeln.

Das Problem ist, dass ich immer dann, wenn ich es versuche, eine Null-Bitmap und die nicht beschreibende, nicht hilfreiche Protokollausgabe erhalte:

12-07 17:01:33.282: D/skia(2971): --- SkImageDecoder::Factory returned null

Ich habe mir folgende Lösungen angesehen:

Lösung liefert die Bitmap zu Byte [] Code verwendet

Hervorgehoben, dass copyPixelsToBuffer () über .compress wesentlich ist

(Zumal es in diesem Fall nicht notwendig ist).

Ich habe den folgenden Testfall ausgeführt, der das Problem definitiv auf das Konvertieren und Wiederherstellen von Code einschränkt. Basierend auf meinem Debugging gibt es eine korrekte Dekodierung, das Byte-Array hat die richtige Größe und ist voll, die Bitmap-Konfigurationen müssen identisch sein, decodeByteArray schlägt einfach fehl:

package com.example.debug;

import Java.nio.ByteBuffer;

import Android.os.Bundle;
import Android.app.Activity;
import Android.graphics.Bitmap;
import Android.graphics.Bitmap.Config;
import Android.graphics.BitmapFactory;
import Android.util.Log;
import Android.view.Menu;
import Android.widget.ImageView;
import Android.widget.RelativeLayout;

public class MainActivity extends Activity {
    RelativeLayout rl = null;
    RelativeLayout.LayoutParams rlp = null;

    ImageView ivBef = null;
    ImageView ivAft = null;

    Bitmap bmBef = null;
    Bitmap bmAft = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TEST
        BitmapFactory.Options bmo = new BitmapFactory.Options();
        bmo.inPreferredConfig = Config.ARGB_8888;

        bmBef = BitmapFactory.decodeFile("/mnt/sdcard/Debug/001.png", bmo);
        byte[] b = bitmapToByteArray(bmBef);
        bmAft = BitmapFactory.decodeByteArray(b, 0, b.length, bmo);

        LinearLayout ll = new LinearLayout(this);

        ivBef = new ImageView(this);
        ivBef.setImageBitmap(bmBef);

        ivAft = new ImageView(this);
        ivAft.setImageBitmap(bmAft);

        ll.addView(ivBef);
        ll.addView(ivAft);

        setContentView(ll);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public static byte[] bitmapToByteArray(Bitmap bm) {
        // Create the buffer with the correct size
        int iBytes = bm.getWidth() * bm.getHeight() * 4;
        ByteBuffer buffer = ByteBuffer.allocate(iBytes);

        // Log.e("DBG", buffer.remaining()+""); -- Returns a correct number based on dimensions
        // Copy to buffer and then into byte array
        bm.copyPixelsToBuffer(buffer);
        // Log.e("DBG", buffer.remaining()+""); -- Returns 0
        return buffer.array();
    }

}

Die vorher Imageview zeigt das Bild korrekt an, die nachher ImageView zeigt nichts an (wie Sie es bei einer Null-Bitmap erwarten würden)

13
B T

Sie übergeben Bitmap in Intent und erhalten Bitmap in der nächsten Aktivität aus dem Bündel. Das Problem ist jedoch, wenn Ihre Bitmap-/Bildgröße zu diesem Zeitpunkt groß ist und das Bild in der nächsten Aktivität nicht geladen wird.

Verwenden Sie unten 2 Lösungen, um dieses Problem zu lösen.

1) Konvertieren Sie zunächst das Image in ein Byte-Array, und übergeben Sie es in Intent. In der nächsten Aktivität erhalten Sie ein Byte-Array von Bundle und Convert in Image (Bitmap) und setzen es in ImageView.

Konvertieren Sie die Bitmap in ein Byte-Array: -

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

Byte-Array in Intent übergeben: -

Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("picture", byteArray);
startActivity(intent);

Holen Sie sich ein Byte-Array aus dem Bundle und konvertieren Sie es in ein Bitmap-Bild: -

Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");

Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);

image.setImageBitmap(bmp);

2) Speichern Sie zuerst das Bild auf der SD-Karte und setzen Sie dieses Bild in der nächsten Aktivität in ImageView.

47
Dipak Keshariya

Das Senden einer Bitmap in einer Bundle von Daten ist eine wirklich schlechte Idee und wäre eine wirklich schlechte Implementierung. Die Datengröße einer Bundle ist 1 MB, wie von Dianne Hackborn (Android Framework Engineer) angegeben.

5
kaderud

Die folgende Methode funktioniert perfekt mit mir, probieren Sie es aus ..

public byte[] convertBitmapToByteArray(Context context, Bitmap bitmap) {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight());
    bitmap.compress(CompressFormat.PNG, 100, buffer);
    return buffer.toByteArray();
}
2
Nermeen

versuche dies:

  bmBef = BitmapFactory.decodeFile("/mnt/sdcard/Debug/001.png", bmo);
  ByteArrayOutputStream baos= new ByteArrayOutputStream();
  bmBef .compress(Bitmap.CompressFormat.PNG, 100, baos);
  byte[] byteArray = baos.toByteArray();
0
G M Ramesh