2012-12-07 115 views
12

目標是將Bitmap轉換爲byte [],在數據的Bundle的活動之間傳遞它,然後在稍後階段將其重新轉換回Bitmap用於在Imageview中顯示。Android:位圖到字節數組和返回:SkImageDecoder :: Factory返回null

的問題是,每當我試試這個,我只是得到一個空的位圖和非描述性的,無益的日誌輸出:

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

我已經看過了以下解決方案:

Solution supplies the bitmap to byte[] code used

Highlighted that copyPixelsToBuffer() is essential over .compress

(特別看到,因爲它是正在這種情況下是必要的)。

我已經運行了下面的測試用例,它肯定會將問題縮小到轉換和還原代碼。根據我的調試,有正確解碼,字節數組的大小正確和完整的,位圖CONFIGS被迫相同,decodeByteArray只是失敗:

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

} 

的前Imageview正確顯示圖像時, ImageView顯示什麼後(如你要做一個空位圖

+0

我覺得問題不是佈局中的位圖問題。 –

+0

問題是(如參考問題所示),與僅複製像素相比,壓縮顯然較慢。我可以理解這些好處,但是在處理小圖標圖像時,它似乎是不必要的開銷。 decodeByteArray只是錯誤的函數調用,因爲圖像在放入數組時未被「編碼」/壓縮? –

+0

@BT請看我的回答,如果我的回答對你有幫助,那麼請接受它。 –

回答

43

你傳入位圖到意向並從bundle中獲取下一個活動的位圖,但問題在於,如果您的位圖/圖像大小較大,那麼圖像在下一個活動中不會加載。

以下使用2解決方案來解決這個問題。

1)首先將圖像轉換爲字節數組,然後傳入Intent,然後在下一個活動中從Bundle獲取字節數組並轉換爲圖像(位圖)並設置爲ImageView。

轉換位圖字節數組: -

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

通行證字節數組到意圖: - 從捆綁

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

獲取字節數組,轉換成位圖圖像: -

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)首先將圖像保存到SDCard中,然後在下一個活動中將此圖像設置爲ImageView。

+0

我已經標記了這個答案,因爲它的工作原理是正確的。本質上,這裏的問題似乎是,如果我只想將像素複製到byte []並傳輸它們,而沒有不必要的壓縮開銷,那麼decodeByteArray是錯誤的函數調用。似乎沒有正確的函數調用從像素的字節數組創建位圖,唯一的選擇是[這裏](http://stackoverflow.com/questions/10770263/decodebytearray-and-copypixelstobuffer-not-working- skimagedecoderfactory-retu)它將字節數組中的像素物理地繪製成位圖畫布 –

+0

你簡直是超棒的dipkaaaa ;-) –

+0

@Prince。它是dipakkk – Abhi

2

下面的方法與我的作品完美期望,給它一個嘗試..

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

試試這個:

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

數據的Bundle發送位圖是一個真正的壞主意,將是一個真正的壞實現。另外,如Dianne Hackborn(Android框架工程師)所述,Bundle的數據大小爲1 MB

+0

這項工作的範圍是使用有限大小的圖標,但是你確實有一個有效的點。在我的實現中,我想我會重新思考(也許在包中使用臨時文件和路徑)。你能提供一個鏈接給你提供的這些信息嗎?對於最大尺寸,我的搜索返回了不同的答案。 –

+1

查看此討論https://groups.google.com/d/msg/android-developers/KKEyW6XdDvg/wgetULOJq3QJ – kaderud

相關問題