例のように、ギャラリーから画像を選択し、BitMapとして取得するアクティビティがあるとします: here
次に、このBitMapを渡して、別のアクティビティのImageViewで使用するようにします。アクティビティ間でバンドルを渡すことができますが、このBitMapをバンドルに保存するにはどうすればよいですか?
または私が取るべき別のアプローチがありますか?
別のアプローチを強くお勧めします。
本当にやりたい場合は可能ですが、メモリを大量に消費し、速度も遅くなります。古い携帯電話と大きなビットマップを使用している場合、機能しない可能性があります。たとえば、intent.putExtra("data", bitmap)
のように、余分なものとして渡すことができます。ビットマップはParcelableを実装しているので、追加することができます。同様に、バンドルにはputParcelable
があります。
アクティビティ間で渡したい場合は、ファイルに保存します。これはより効率的で、作業量が少なくなります。 MODE_PRIVATEを使用して、他のアプリからアクセスできないプライベートファイルをデータフォルダーに作成できます。
Parcelableとして渡すと、Java BINDER FAILUREエラーが発生します。したがって、解決策は次のとおりです。ビットマップが小さい場合、たとえばサムネイル、パスバイト配列として、次のアクティビティで表示するビットマップを作成します。
呼び出しアクティビティで...
Intent i = new Intent(this, NextActivity.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startActivity(i);
...および受信アクティビティで
if(getIntent().hasExtra("byteArray")) {
ImageView previewThumbnail = new ImageView(this);
Bitmap b = BitmapFactory.decodeByteArray(
getIntent().getByteArrayExtra("byteArray"),0,getIntent().getByteArrayExtra("byteArray").length);
previewThumbnail.setImageBitmap(b);
}
@EboMikeが示唆するように、ビットマップをmyImageという名前のファイルに保存しました。これは、他のアプリにアクセスできないアプリケーションの内部ストレージにあります。その部分のコードは次のとおりです。
public String createImageFromBitmap(Bitmap bitmap) {
String fileName = "myImage";//no .png or .jpg needed
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
fo.write(bytes.toByteArray());
// remember close file output
fo.close();
} catch (Exception e) {
e.printStackTrace();
fileName = null;
}
return fileName;
}
次のアクティビティでは、次のコードを使用して、このファイルmyImageをビットマップにデコードできます。
Bitmap bitmap = BitmapFactory.decodeStream(context
.openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this
注 nullのチェックとビットマップのスケーリングは省略されています。
アクティビティ
Activites間でビットマップを渡すには
Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);
そしてActivityクラスでは
Bitmap bitmap = getIntent().getParcelableExtra("bitmap");
フラグメント
フラグメント間でビットマップを渡すには
SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);
SecondFragment内で受信するには
Bitmap bitmap = getArguments().getParcelable("bitmap");
大きなビットマップの転送(ビットマップの圧縮)
失敗したバインダートランザクションを取得している場合、これは、1つのアクティビティから別のアクティビティに大きな要素を転送することにより、バインダートランザクションバッファーを超えていることを意味します。
その場合、ビットマップをバイトの配列として圧縮してから、別のアクティビティで圧縮解除する必要があります、このように
FirstActivity
Intent intent = new Intent(this, SecondActivity.class);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray();
intent.putExtra("bitmapbytes",bytes);
SecondActivity
byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
first.Javaで
Intent i = new Intent(this, second.class);
i.putExtra("uri",uri);
startActivity(i);
second.Java
Bundle bd = getIntent().getExtras();
Uri uri = bd.getParcelable("uri");
Log.e("URI", uri.toString());
try {
Bitmap bitmap = Media.getBitmap(this.getContentResolver(), uri);
imageView.setImageBitmap(bitmap);
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ビットマップは Parcelable ですので、[putExtra(String、Parcelable)] [2]メソッドを使用して追加できますが、ベストプラクティスであるかどうかはわかりません。サイズの大きいデータの場合は、単一の場所と両方のアクティビティからの使用。
[2]: http://developer.Android.com/reference/Android/content/Intent.html#putExtra(Java.lang.String 、Android.os.Parcelable)
次のアクティビティに意図したいところからこのコードを書きます。
yourimageView.setDrawingCacheEnabled(true);
Drawable drawable = ((ImageView)view).getDrawable();
Bitmap bitmap = imageView.getDrawingCache();
Intent intent = new Intent(getBaseContext(), NextActivity.class);
intent.putExtra("Image", imageBitmap);
NextActivity.classのonCreate関数で
Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");
トランザクションバインダーの1 MBの制限を超えないように、ビットマップを少しスケーリングし直す必要がありました。 400を画面に適応させることも、動的にすることもできます。これは単なる例です。それはうまく機能し、品質は素晴らしいです。また、画像を保存してからロードするよりもはるかに高速ですが、サイズに制限があります。
public void loadNextActivity(){
Intent confirmBMP = new Intent(this,ConfirmBMPActivity.class);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bmp = returnScaledBMP();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
confirmBMP.putExtra("Bitmap",bmp);
startActivity(confirmBMP);
finish();
}
public Bitmap returnScaledBMP(){
Bitmap bmp=null;
bmp = tempBitmap;
bmp = createScaledBitmapKeepingAspectRatio(bmp,400);
return bmp;
}
次のコードでnextActivityのbmpを回復した後:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_confirmBMP);
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("Bitmap");
}
私の答えが何らかの形で役立つことを願っています。あいさつ
このようなバンドルを使用せずに短い画像を渡すことができますこれは送信者.classファイルのコードです
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher;
Intent intent = new Intent();
Intent.setClass(<Sender_Activity>.this, <Receiver_Activity.class);
Intent.putExtra("Bitmap", bitmap);
startActivity(intent);
これは、レシーバークラスファイルコードです。
Bitmap bitmap = (Bitmap)this.getIntent().getParcelableExtra("Bitmap");
ImageView viewBitmap = (ImageView)findViewById(R.id.bitmapview);
viewBitmap.setImageBitmap(bitmap);
圧縮する必要はありません。それでおしまい