在 Android 中使用 Intent 在活动中传递 android 位图数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11010386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:43:18  来源:igfitidea点击:

Passing android Bitmap Data within activity using Intent in Android

androidandroid-intentbitmap

提问by adi.zean

I hava a Bitmap variable named bmpin Activity1 , and I want to send the bitmap to Activity2

我有一个bmp在 Activity1 中命名的 Bitmap 变量,我想将位图发送到 Activity2

Following is the code I use to pass it with the intent.

以下是我用来传递它的意图的代码。

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",bmp);
startActivity(in1);

And in Activity2 I try to access the bitmap using the following code

在 Activity2 中,我尝试使用以下代码访问位图

Bundle ex = getIntent().getExtras();
Bitmap bmp2 = ex.getParceable("image");
ImageView result = (ImageView)findViewById(R.Id.imageView1);
result.setImageBitmap(bmp);

The application runs without an exception but it does not give the expected result

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

回答by Zaid Daghestani

Convert it to a Byte array before you add it to the intent, send it out, and decode.

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

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

Then in Activity 2:

然后在活动 2 中:

byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);


edit

编辑

Thought I should update this with best practice:

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

In your first activity, you should save the Bitmap to disk then load it up in the next activity. Make sure to recycle your bitmap in the first activity to prime it for garbage collection:

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

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

In Activity 2, load up the bitmap:

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

Cheers!

干杯!

回答by android developer

Sometimes, the bitmap might be too large for encode&decode or pass as a byte array in the intent. This can cause either OOM or a bad UI experience.

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

I suggest to consider putting the bitmap into a static variable of the new activity (the one that uses it) which will carefully be null when you no longer need it (meaning in onDestroy but only if "isChangingConfigurations" returns false).

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

回答by Vignesh Kumar

Simply we can pass only Uri of the Bitmap instead of passing Bitmap object. If Bitmap object is Big, that will cause memory issue.

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

FirstActivity.

第一活动。

intent.putExtra("uri", Uri);

From SecondActivity we get back bitmap.

从 SecondActivity 我们得到位图。

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));

回答by Hamed Jaliliani

Kotlin Code for send Bitmap to another activity by intent:

用于通过意图将位图发送到另一个活动的 Kotlin 代码:

1- in First Activity :

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- In Activity two (Read the bitmap image) :

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- if you need to set it as background for a view, like ConstraintLayout or... :

3- 如果您需要将其设置为视图的背景,例如 ConstraintLayout 或...:

 if (bitmap != null) {
     //Convert bitmap to BitmapDrawable
     var bitmapDrawable = BitmapDrawable( resources , bitmap)
      root_constraintLayout.backgroundDrawable = bitmapDrawable
   }

回答by murali krish

We can also solve this without passing data through intent. Just store the image in the memory and in the next Activity just load the image from that location, which can also avoid app crash from passing large bitmap data. Note: You need not even pass the location path to the intent, remember the path and use it.

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

回答by Micro

I would like to also post a best practices answer for those looking to do this (but may be asking the wrong question).

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

Instead of passing a bitmap around (which I presume you downloaded from the network, otherwise, you would already have a file reference to it), I recommend using an image loader such as Universal Image Loaderto download an image into an ImageView. You can configure it to then cache the image to disk:

与其传递位图(我假设您是从网络下载的,否则您已经有了对它的文件引用),我建议使用图像加载器(例如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);

Now, just pass the image URL in your intent and use the UIL to load the image. In your newly created activity for example, the image will load instantly because it is loading from the cache - even if your image URL has expired since the download.

现在,只需在您的意图中传递图像 URL 并使用 UIL 加载图像。例如,在您新创建的活动中,图像将立即加载,因为它是从缓存加载的 - 即使您的图像 URL 自下载后已过期。

回答by Prashant Mishra

Bundle b = new Bundle();
b.putSerializable("Image", Bitmap);
mIntent.putExtras(b);
startActivity(mIntent);