【问题标题】:pass a bitmap image from one activity to another将位图图像从一个活动传递到另一个活动
【发布时间】:2012-11-27 05:00:30
【问题描述】:

在我的应用程序中,我从图库中显示图片数量,一旦我选择一张图片,图片就会发送到新活动,在该活动中所选图片将被设置为背景。但是,我能够从图库中获取图像,但一旦我选择一个应用程序就会崩溃。提前致谢

Activity-1(图片显示在图库中,所选图片发送到新活动)

public class Gallery extends Activity {

private static int RESULT_LOAD_IMAGE = 1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery);

        Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);


        buttonLoadImage.setOnClickListener(new View.OnClickListener() {

            public void onClick(View arg0) {

                Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

                startActivityForResult(i, RESULT_LOAD_IMAGE);
            }
        });
    }



    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {






            Uri contentUri = data.getData();          
            String[] proj = { MediaStore.Images.Media.DATA };         
            Cursor cursor = managedQuery(contentUri, proj, null, null, null);         
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);         
            cursor.moveToFirst();         
            String tmppath = cursor.getString(column_index);           
            Bitmap croppedImage = BitmapFactory.decodeFile(tmppath);


            // Bitmap croppedImage = BitmapFactory.decodeFile(croppedImage);
            Intent intent = new Intent(Gallery.this,GesturesActivity.class);
            intent.putExtra("bmp",croppedImage);
            startActivity(intent);

            Log.v("sending image","sending image");


        }


    }
}

Activity-1(XML)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/background"
    >
    <ImageView
            android:id="@+id/imgView"
            android:layout_width="fill_parent"
            android:layout_weight="1" android:layout_height="wrap_content"></ImageView>
    <Button 
            android:layout_height="wrap_content" 
            android:text="Load Picture" 
            android:layout_width="wrap_content" 
            android:id="@+id/buttonLoadPicture" 
            android:layout_weight="0" 
            android:layout_gravity="center"></Button>
</LinearLayout>

Activity-2(应将所选图像设置为屏幕背景图像的活动)

  public class GesturesActivity extends Activity {


        private final int MENU_CAMERA = Menu.FIRST;


        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);


            Bitmap bmp = (Bitmap)this.getIntent().getParcelableExtra("bmp");
            BitmapDrawable background = new BitmapDrawable(bmp);
            getWindow().setBackgroundDrawable(background);  //background image of the screen



            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.advert);
            View view = new SandboxView(this, bitmap);

            setContentView(view);
        }



        public boolean onPrepareOptionsMenu(Menu menu) {
            menu.clear();

                menu.add(0, 11, 0, "Take Snapshot");

                    return super.onPrepareOptionsMenu(menu);
        }


        public boolean onOptionsItemSelected(MenuItem item) {

            return super.onOptionsItemSelected(item);
        }



    }

【问题讨论】:

标签: android android-intent bitmap bitmapimage


【解决方案1】:

有 3 个解决方案可以解决此问题。

1) 首先将Image转换为字节数组,然后传入Intent,在下一个活动中从Bundle中获取字节数组并转换为Image(Bitmap)并设置为ImageView。

将位图转换为字节数组:-

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

将字节数组传递给意图:-

Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("picture", byteArray);
startActivity(intent);

从Bundle中获取字节数组并转换为位图图像:-

Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");

Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);

image.setImageBitmap(bmp);

2) 首先将图像保存到 SDCard 中,然后在下一个活动中将此图像设置为 ImageView。

3) 将位图传递到 Intent 并从捆绑包中获取下一个活动中的位图,但问题是如果您的位图/图像大小当时很大,则图像不会在下一个活动中加载。

【讨论】:

  • :根据您的第一个解决方案,如果我想将图像视图转换为位图,我该怎么做?
【解决方案2】:

既然您是从图库中检索图像,为什么不将 id 传递给下一个 Activity 并在该 Activity 中检索图像,而不是传递图像?这将帮助您提高内存和性能。

【讨论】:

  • +1,这是最方便的方式。存储用户选择的图像 ID 并将该 ID 传递给下一个活动。
【解决方案3】:

Bitmap 实现了 Parcelable,因此您可以随时在 Intent 中传递它。试试下面的代码:

第一个活动。

Intent mIntent = new Intent(this, ActivityTwo.class);
mIntent.putExtra("bmp_img", bmp);

要在目标活动中获取输出,请尝试:

第二个活动。

Bitmap mBitmap = (Bitmap) intent.getParcelableExtra("bmp_img");

您总是使用 getParcelableExtra("key") 来获取 Activity 中传递的 Bitmap。

【讨论】:

  • @oren 大位图的替代方案是什么?
  • @AnshulTyagi 如果您正在处理大型位图,您可以将它们保存到内部存储中,将文件名传递给从内部存储读取它的额外到第二个活动。我用它来传输屏幕截图,效果很好。
【解决方案4】:

我认为您可以通过将位图定义为静态并通过调用 classname.bitmap 来获取位图..并在下一个活动中设置为背景

【讨论】:

    【解决方案5】:

    活动

    在 Activity 之间传递位图

    Intent intent = new Intent(this, Activity.class);
    intent.putExtra("bitmap", bitmap);
    

    在 Activity 类中

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

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

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

    在第一个活动中

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

    【讨论】:

      【解决方案6】:

      IGP 总结得很清楚,但在我看来,最有效的方法是将图像的 URI 传递给下一个活动,而不是位图本身。我实际上不确定是否可以使用 Intents 将整个 Bitmaps(或转换后的 ByteArrays)数据从一个活动传递到另一个活动 - 我相信 Bundle 可以包含多少数据是有限制的。

      而是传递您用来在第一个活动中显示图像的引用。我假设您正在使用某种延迟加载?如果没有,我强烈建议你这样做。这样您就可以简单地通过 URI 重新查询 Bitmap。

      但是,我可以从图库中获取图像,但只要我 选择一个应用程序崩溃

      我仍然对这些问题如何达到 SO 感到困惑。查看日志,也许您可​​以自己解决。

      【讨论】:

        【解决方案7】:

        使用它可以将位图传递给另一个活动。

        如果你使用的是drawable,那么先将drawable转换为位图。

        Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
        

        要使用 Intent 将该位图传递给另一个活动,请使用下面的代码 sn-p。

        intent.putExtra("Bitmap", bitmap);
        

        如果要在另一个活动中获取该位图意图,请使用此

        Bitmap bitmap = (Bitmap)this.getIntent().getParcelableExtra("Bitmap");
        

        关注这个 Link for More Detail.

        【讨论】:

          【解决方案8】:

          我发现最简单(但绝对不是最优雅)的方法是使用静态类成员。例如:

          class PassedData
          {
              public Bitmap bm1, bm2, etc;
          
              private PassedData current;
          
              public static PassedData getCurrent() {return current;}
          
              public PassedData()
              {
                  current = this;
              }
          }
          

          那么每个activity都可以引用PassedData.getCurrent()。

          【讨论】:

            猜你喜欢
            • 2012-03-05
            • 1970-01-01
            • 2012-07-16
            • 1970-01-01
            • 1970-01-01
            • 2018-03-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多