2012-12-07 7 views
12

Celem jest konwersja Bitmap do byte [], przekazać ją pomiędzy działaniami w Bundle danych, a następnie przestawienia go z powrotem do Bitmap na późniejszym etapie do wyświetlania w postaci Imageview.Android: Bitmap do Byte Array i tył: SkImageDecoder :: Fabryka wróciła zerowy

Problem jest, że gdy próbuję to po prostu uzyskać zerową bitmapę i non-opisową, niepomocny wyjście dziennika:

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

Mam spojrzał na następujących rozwiązań:

Solution supplies the bitmap to byte[] code used

Highlighted that copyPixelsToBuffer() is essential over .compress

(bardziej, że jest to n niezbędne w tym przypadku).

Uruchomiłem następujący przypadek testowy, który zdecydowanie zawęża problem do konwersji i przywracania kodu. Na podstawie mojego debugowania, nie jest poprawne dekodowanie, tablica bajtów jest prawidłowy rozmiar i pełny, configs bitmapy są zmuszeni być taka sama, decodeByteArray jest tylko w przypadku braku:

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 poprawnie wyświetla obrazu, po ImageView pokazuje nic (jak można się spodziewać z pustym bitmapy

+0

Myślę, że problem nie jest problemem bitmapy w układzie. –

+0

Problem jest (jak pokazuje jedno z pytań referencyjnych), kompresja jest oczywiście powolna w porównaniu do samego kopiowania pikseli. Rozumiem zalety, ale podczas pracy z małymi ikonami wydaje się zbędne. Czy decodeByteArray jest po prostu błędnym wywołaniem funkcji, biorąc pod uwagę, że obraz nie jest "zakodowany"/skompresowany po umieszczeniu w tablicy? –

+0

@BT Proszę zobaczyć moją odpowiedź i jeśli moja odpowiedź ci pomoże, to proszę, zaakceptuj to. –

Odpowiedz

43

są przechodzącą bitmapę intencyjnego i pobierz bitmapę w następnym działaniu z pakietu, ale problem polega na tym, że rozmiar bitmapy/obrazu jest duży w tym czasie, gdy obraz nie jest ładowany w następnym działaniu.

Użyj poniżej 2 rozwiązań, aby rozwiązać ten problem.

1) Najpierw skonwertuj obraz do tablicy bajtowej, a następnie przejdź do zamiaru, aw następnym ćwiczeniu pobierz tablicę bajtów z pakietu i przekształć w obraz (mapa bitowa) i ustaw w widoku obrazu. Bitmapy

Konwersja do 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(); 

Przełęcz bajt tablicy w intencji: -

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

Get Byte Array z Bundle i przekształcić Bitmap Image: -

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) Najpierw Zapisz obraz na karcie SD iw następnym działaniu ustaw ten obraz w ImageView.

+0

Zaznaczam tę odpowiedź jako prawidłową, ponieważ działa. Zasadniczo problem tutaj wydaje się, że jeśli chcę po prostu skopiować piksele do bajtu [] i przenieść je, bez niepotrzebnego narzutu kompresji, to dekodeByteArray jest niewłaściwym wywołaniem funkcji. Wygląda na to, że nie ma poprawnej funkcji wywoływania tworzenia bitmapy z tablicy bajtów pikseli, jedyną opcją jest to, że [tutaj] (http://stackoverflow.com/questions/10770263/decodebytearray-and-copypixelstobuffer-not-working- skimagedecoderfactory-retu), który fizycznie maluje piksele z tablicy bajtów na płótnie bitmapowym –

+0

Jesteś po prostu świetny dipkaaaa ;-) –

+0

@ Prince. to dipakkk – Abhi

2

Poniższa metoda działa doskonale ze mną spróbować ..

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

spróbuj tego:

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

Wysyłanie bitmapę w Bundle danych jest prawdziwe zły pomysł, a byłby to prawdziwy złe wdrożenie. Ponadto rozmiar danych Bundle jest 1 MB, jak podała Dianne Hackborn (inżynier systemu Android).

+0

Zakres tej pracy polega na użyciu ikon o ograniczonych rozmiarach, ale tak, masz ważny punkt. W mojej implementacji, myślę, że będę przemyśleć (może użyć plików tymczasowych i ścieżki w pakiecie). Czy możesz podać link do podanych przez siebie informacji? Moje wyszukiwanie zwróciło różne odpowiedzi co do maksymalnego rozmiaru. –

+1

Zobacz tę dyskusję https://groups.google.com/d/msg/android-developers/KKEyW6XdDvg/wgetULOJq3QJ – kaderud