你如何使用bundle传递android活动之间的图像(位图)?

dam*_*shu 50 android bundle image

假设我有一个从库中选择图像的活动,并将其作为BitMap检索,就像示例:here

现在,我想传递此BitMap以在ImageView中用于另一个活动.我知道bundle可以在活动之间传递,但是我如何将这个BitMap存储到bundle中?

还是我应该采取另一种方法?

Ebo*_*ike 49

我强烈推荐一种不同的方法.

如果你真的想要这样做,它可能会花费大量内存而且速度也很慢.如果你有一个旧手机和一个大位图,它可能无法正常工作.例如,您可以将其作为额外传递intent.putExtra("data", bitmap).Bitmap实现了Parcelable,因此您可以将其添加到额外的位置.同样,捆绑包有putParcelable.

如果你想在活动之间传递它,我会将它存储在一个文件中.这样效率更高,而且工作量更少.您可以使用任何其他应用无法访问的MODE_PRIVATE在数据文件夹中创建私人文件.

  • 如果我只是将图像的路径传递给其他活动怎么办? (5认同)
  • 当然,那是完美的!我认为Bitmap是由您的活动临时创建的,这就是您必须传递它的原因.(如果您像这样DID创建它,您可能希望将其保存到本地文件夹然后重新加载它). (2认同)
  • 顺便说一下,还有一件事 - 在我的咆哮中,它说它很糟糕,我说的是全尺寸的图像.如果你有较小的位图,那么将它们作为Parcelable传递肯定是可以的. (2认同)

Har*_*mes 41

如果将它作为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);
Run Code Online (Sandbox Code Playgroud)

......并在你的接收活动中

if(getIntent().hasExtra("byteArray")) {
    ImageView previewThumbnail = new ImageView(this);
    Bitmap b = BitmapFactory.decodeByteArray(
        getIntent().getByteArrayExtra("byteArray"),0,getIntent().getByteArrayExtra("byteArray").length);        
    previewThumbnail.setImageBitmap(b);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果位图不是很小? (36认同)
  • 你能解释一下这有助于避免Java Binder失败吗? (8认同)
  • 当位图很小时我会使用Parcelable.当你在bundle中传递超过1mb的数据时会出现问题. (2认同)

Ill*_*ent 22

正如@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;
}
Run Code Online (Sandbox Code Playgroud)

然后在下一个活动中,您可以使用以下代码将此文件myImage解码为位图:

Bitmap bitmap = BitmapFactory.decodeStream(context
                    .openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this
Run Code Online (Sandbox Code Playgroud)

注意很多都会检查null和缩放位图.

  • @ alfo888_ibg我认为你不需要删除图像,因为每次使用该功能都会覆盖前一个图像.但是,如果您愿意,可以删除它 (2认同)

cap*_*wag 5

活动

在活动之间传递位图

Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);
Run Code Online (Sandbox Code Playgroud)

并在Activity类中

Bitmap bitmap = getIntent().getParcelableExtra("bitmap");
Run Code Online (Sandbox Code Playgroud)

分段

在片段之间传递位图

SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);
Run Code Online (Sandbox Code Playgroud)

在SecondFragment内部接收

Bitmap bitmap = getArguments().getParcelable("bitmap");
Run Code Online (Sandbox Code Playgroud)

传输大位图(压缩位图)

如果您的活页夹交易失败,这意味着您将活页夹大笔交易从一个活动转移到另一活动,从而超出了活页夹交易缓冲区。

因此,在这种情况下,您必须将位图压缩为字节数组,然后在另一个活动中将其解压缩,如下所示

在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);
Run Code Online (Sandbox Code Playgroud)

而在SecondActivity中

byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Run Code Online (Sandbox Code Playgroud)