Activity1にbmp
という名前のビットマップ変数があり、ビットマップをActivity2に送信したい
以下は、意図して渡すために使用するコードです。
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",bmp);
startActivity(in1);
そして、Activity2では、次のコードを使用してビットマップにアクセスしようとします
Bundle ex = getIntent().getExtras();
Bitmap bmp2 = ex.getParceable("image");
ImageView result = (ImageView)findViewById(R.Id.imageView1);
result.setImageBitmap(bmp);
アプリケーションは例外なく実行されますが、期待される結果は得られません
インテントに追加して送信し、デコードする前に、バイト配列に変換します。
//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);
次に、アクティビティ2で:
byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
編集
ベストプラクティスでこれを更新する必要があると思った:
最初のアクティビティでは、ビットマップをディスクに保存し、次のアクティビティでロードする必要があります。最初のアクティビティでビットマップをリサイクルして、ガベージコレクションの準備をしてください。
アクティビティ1:
try {
//Write file
String filename = "bitmap.png";
FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
//Cleanup
stream.close();
bmp.recycle();
//Pop intent
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image", filename);
startActivity(in1);
} catch (Exception e) {
e.printStackTrace();
}
アクティビティ2で、ビットマップをロードします。
Bitmap bmp = null;
String filename = getIntent().getStringExtra("image");
try {
FileInputStream is = this.openFileInput(filename);
bmp = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
乾杯!
場合によっては、ビットマップが大きすぎてエンコードおよびデコードできなかったり、インテントでバイト配列として渡されることがあります。これにより、OOMまたは不適切なUIエクスペリエンスが発生する可能性があります。
ビットマップを、新しいアクティビティ(それを使用するもの)の静的変数に入れることを検討することをお勧めします。
ビットマップオブジェクトを渡すのではなく、ビットマップのUriだけを渡すことができます。ビットマップオブジェクトが大きい場合、メモリの問題が発生します。
FirstActivity。
intent.putExtra("uri", Uri);
SecondActivityからビットマップを取得します。
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));
意図によりビットマップを別のアクティビティに送信するためのKotlinコード:
1-最初のアクティビティ:
val i = Intent(this@Act1, Act2::class.Java)
var bStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 50, bStream)
val byteArray = bStream.toByteArray()
i.putExtra("image", byteArray )
startActivity(i)
2-アクティビティ2(ビットマップイメージの読み取り):
var bitmap : Bitmap? =null
if (intent.hasExtra("image")){
//convert to bitmap
val byteArray = intent.getByteArrayExtra("image")
bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
3- ConstraintLayoutまたは...のように、ビューの背景として設定する必要がある場合:
if (bitmap != null) {
//Convert bitmap to BitmapDrawable
var bitmapDrawable = BitmapDrawable( resources , bitmap)
root_constraintLayout.backgroundDrawable = bitmapDrawable
}
また、これを実行しようとしている人のためにベストプラクティスの回答を投稿したいと思います(ただし、間違った質問をしている可能性があります)。
ビットマップを渡すのではなく(ネットワークからダウンロードしたと仮定します。そうしないと、既にファイルへの参照があります)、 niversal Image Loader などのイメージローダーを使用して、 ImageViewへの画像。イメージをディスクにキャッシュするように構成できます。
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.build();
ImageLoader.getInstance().init(config);
次に、画像URLをインテントに渡し、UILを使用して画像をロードします。たとえば、新しく作成されたアクティビティでは、キャッシュから読み込んでいるため、画像はすぐに読み込まれます-ダウンロード後に画像のURLが期限切れになった場合でも。
また、データをインテントに渡すことなくこれを解決できます。画像をメモリに保存し、次のアクティビティでその場所から画像をロードするだけです。これにより、大きなビットマップデータを渡すことでアプリがクラッシュすることも回避できます。注:場所のパスをインテントに渡し、パスを覚えて使用する必要さえありません。