78

我有一个名为 Activity1 的 Bitmap 变量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);

应用程序无异常运行,但未给出预期结果

4

7 回答 7

217

在将其添加到意图、发送出去和解码之前,将其转换为字节数组。

//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);

编辑

认为我应该用最佳实践更新它:

在您的第一个活动中,您应该将位图保存到磁盘,然后在下一个活动中加载它。确保在第一个活动中回收您的位图,以便为垃圾收集做好准备:

活动一:

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

干杯!

于 2012-06-13T08:03:24.773 回答
13

有时,位图可能太大而无法编码和解码,或者在意图中作为字节数组传递。这可能会导致 OOM 或糟糕的 UI 体验。

我建议考虑将位图放入新活动(使用它的那个)的静态变量中,当您不再需要它时,该变量将谨慎地为空(在 onDestroy 中,但仅当“isChangingConfigurations”返回 false 时)。

于 2015-05-21T06:39:41.903 回答
4

简单地说,我们可以只传递 Bitmap 的 Uri 而不是传递 Bitmap 对象。如果 Bitmap 对象很大,则会导致内存问题。

第一活动。

intent.putExtra("uri", Uri);

从 SecondActivity 我们得到位图。

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));
于 2016-11-21T07:30:04.997 回答
2

通过 Intent 将 Bitmap 发送到另一个活动的 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- 在活动二中(读取位图图像):

 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
   }
于 2019-02-17T13:12:26.900 回答
0

我们也可以在不通过意图传递数据的情况下解决这个问题。只需将图像存储在内存中,在下一个 Activity 中只需从该位置加载图像,这也可以避免应用程序因传递大量位图数据而崩溃。注意:您甚至不需要将位置路径传递给意图,记住路径并使用它。

于 2016-02-10T09:41:00.547 回答
0

我还想为那些希望这样做的人发布一个最佳实践答案(但可能会问错问题)。

与其传递位图(我假设您是从网络上下载的,否则,您已经有了对它的文件引用),我建议使用诸如Universal 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 自下载后已过期。

于 2016-05-13T23:57:30.060 回答
-7
Bundle b = new Bundle();
b.putSerializable("Image", Bitmap);
mIntent.putExtras(b);
startActivity(mIntent);
于 2012-06-13T08:03:51.893 回答