web-dev-qa-db-fra.com

Android: bitmap vers octet, tableau et retour: SkImageDecoder :: Factory a renvoyé la valeur null

Le but est de convertir une Bitmap en byte [], de la transmettre entre les activités dans une Bundle de données, puis de la reconvertir en une Bitmap à un stade ultérieur pour affichage dans une Imageview.

Le problème est que chaque fois que j'essaie, j'obtiens simplement un bitmap nul et une sortie de journal non descriptive et inutile:

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

J'ai examiné les solutions suivantes:

Solution fournit le bitmap en octet [] code utilisé

Souligne que copyPixelsToBuffer () est essentiel pour .compress

(Surtout vu que ce n'est pas nécessaire dans ce cas).

J'ai lancé le scénario de test suivant, qui limite définitivement le problème à la conversion et à la restauration du code. Sur la base de mon débogage, le décodage est correct, le tableau d'octets est de taille correcte et complet, les configurations Bitmap sont forcées d'être identiques, decodeByteArray échoue:

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();
    }

}

Before Imageview affiche correctement l'image, after after ImageView ne montre rien (comme on peut s'y attendre avec un bitmap null

13
B T

Vous transmettez Bitmap à Intent et obtenez bitmap dans l'activité suivante de l'ensemble, mais le problème est que si votre taille Bitmap/Image est grande à ce moment, l'image n'est pas chargée dans l'activité suivante.

Utilisez ci-dessous 2 solutions pour résoudre ce problème.

1) Commencez par convertir une image en tableau d’octets, puis passez à l’intention. Dans l’activité suivante, obtenez un tableau d’octets provenant de l’ensemble et convertissez en image (bitmap) et définissez-le dans ImageView.

Convertir un bitmap en tableau d'octets: -

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

Passer un tableau d'octets dans l'intention: -

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

Obtenir le tableau d'octets du paquet et convertir en image bitmap: -

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) Commencez par enregistrer une image dans la carte SD puis, dans l’activité suivante, définissez cette image dans ImageView.

47
Dipak Keshariya

L'envoi d'un bitmap dans une Bundle de données est une très mauvaise idée et une très mauvaise implémentation. En outre, la taille des données d'une Bundle est 1 MB, comme l'a déclaré Dianne Hackborn (ingénieur de structure Android).

5
kaderud

La méthode suivante fonctionne parfaitement avec moi, essayez-la ..

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

essaye ça:

  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