目標は、Bitmap
を_byte []
_に変換し、Bundle
のデータ内のアクティビティ間で渡し、後でBitmap
に再変換することです。 Imageview
に表示するためのステージ。
問題は、これを試すたびに、nullビットマップと、説明的ではない、役に立たないログ出力が得られることです。
12-07 17:01:33.282: D/skia(2971): --- SkImageDecoder::Factory returned null
私は次の解決策を見ました:
ソリューションは、使用されるbyte []コードにビットマップを提供します
copyPixelsToBuffer()が.compressよりも重要であることを強調
(特にこの場合は必要ないので見てください)。
次のテストケースを実行しました。これにより、コードの変換と復元に問題が確実に絞り込まれます。私のデバッグに基づいて、正しいデコードが行われ、バイト配列は正しいサイズとフルであり、ビットマップ構成は強制的に同じになり、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();
}
}
_
Before Imageview
は画像を正しく表示し、after ImageView
は何も表示しません(nullビットマップで予想されるように)
BitmapをIntentに渡し、バンドルから次のアクティビティでビットマップを取得しますが、問題は、その時点でビットマップ/画像サイズが大きい場合、次のアクティビティで画像が読み込まれないことです。
この問題を解決するには、以下の2つのソリューションを使用してください。
1)最初に画像をバイト配列に変換してからIntentに渡し、次のアクティビティでバンドルからバイト配列を取得し、Image(Bitmap)に変換して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に設定します。
Bundle
のデータでビットマップを送信するのは本当に悪い考えであり、実際の悪い実装になります。また、Bundle
のデータサイズは1 MB
Dianne Hackborn(Androidフレームワークエンジニア)が述べたとおり。
次の方法は私にぴったりです。試してみてください。
public byte[] convertBitmapToByteArray(Context context, Bitmap bitmap) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight());
bitmap.compress(CompressFormat.PNG, 100, buffer);
return buffer.toByteArray();
}
これを試して:
bmBef = BitmapFactory.decodeFile("/mnt/sdcard/Debug/001.png", bmo);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
bmBef .compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] byteArray = baos.toByteArray();