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

时间:2010-12-04 05:49:23

标签: android image bundle

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

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

或者我应该采取另一种方法吗?

9 个答案:

答案 0 :(得分:46)

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

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

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

答案 1 :(得分:40)

如果将其作为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);
}

答案 2 :(得分: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;
}

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

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

注意大量检查null和缩放位图是否被忽略。

答案 3 :(得分:5)

<强>活动

在Activites

之间传递位图
Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);

并在“活动课程”

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

传输大位图(压缩位图)

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

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

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

答案 4 :(得分:2)

位图是Parcelable所以你可以使用[putExtra(String,Parcelable)] [2]方法添加,但不确定它是最佳实践,如果它是大尺寸数据,最好存储在单一地点并从两个活动中使用。

[2]:http://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String,android.os.Parcelable)

答案 5 :(得分:2)

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

答案 6 :(得分:1)

我不得不将位图重新缩放一点,以不超过事务绑定器的1mb限制。你可以调整400你的屏幕或使它成为dinamic它只是一个例子。 它工作正常,质量很好。 它也比保存图像和加载后快得多,但你有尺寸限制。

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

}

我希望我的答案在某种程度上有所帮助。 问候

答案 7 :(得分:1)

将您想要Intent的代码写入下一个活动。

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

答案 8 :(得分:1)

您可以简单地传递图像而不使用像这样的包 这是发件人.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);

无需压缩。 那是