假设我有一个活动从图库中选择图像并将其作为位图检索,就像这个例子:here
现在,我想将此位图传递给另一个活动中的ImageView使用。 我知道可以在活动之间传递bundle,但是我应该如何将此位图存储到bundle中?
还是我应该采取另一种方法?
我非常推荐采用不同的方法。
如果你真的想这样做,虽然有可能,但需要大量的内存并且速度也很慢。如果你的手机比较老并且位图比较大,它可能无法正常工作。例如,你可以将它作为额外项传递,intent.putExtra("data", bitmap)
。Bitmap实现了Parcelable接口,因此你可以将它放入额外项中。同样,Bundle也有putParcelable
。
如果你想在活动之间传递它,我建议你将它存储在文件中。这更有效率,也更少工作。你可以使用MODE_PRIVATE在数据文件夹中创建私有文件,这些文件对其他应用程序不可访问。
如果您将它作为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);
}
如@EboMike所建议,我将位图保存在名为myImage的文件中,该文件存储在我的应用程序内部存储中,其他应用程序无法访问。这是该部分的代码:
如@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 解码为位图:
然后在下一个活动中,您可以使用以下代码将文件 myImage 解码为位图:
Bitmap bitmap = BitmapFactory.decodeStream(context
.openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this
注意:省略了很多检查 null 和缩放位图的步骤。
活动
在活动之间传递位图
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);
byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
在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();
}
在您想要意图进入下一个活动的位置编写此代码。
yourimageView.setDrawingCacheEnabled(true);
Drawable drawable = ((ImageView)view).getDrawable();
Bitmap bitmap = imageView.getDrawingCache();
Intent intent = new Intent(getBaseContext(), NextActivity.class);
intent.putExtra("Image", imageBitmap);
Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");
您可以通过以下方式简短地传递图像,而无需使用bundle
这是发送器的.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);
不需要压缩。 就是这样。
我不得不对位图进行一些缩放,以避免超过事务绑定器的1mb限制。您可以根据自己的屏幕调整400或使其动态,这只是一个示例。 它运行良好,质量也很好。 它也比保存图像并在之后加载要快得多,但您有尺寸限制。
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;
}
在您的下一个Activity中使用以下代码恢复bmp后:protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_confirmBMP);
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("Bitmap");
}
我希望我的回答在某种程度上对您有所帮助。 问候
最好将文件保存在temp/cache文件夹中,并像我一样通过意图数据传递文件路径。以下是示例代码:
从按钮点击事件开始(这里的bitmapFullScreen是我从Live Server收集的位图数据)
Intent intent = new Intent(context, FullscreenActivity.class);
String fPath = CreateTempFile(bitmapFullScreen);
if(!StringUtils.isEmpty(fPath)) {
intent.putExtra("image", fPath);
startActivity(intent);
}
public String CreateTempFile(Bitmap mBitmap) {
File f3 = new File(Environment.getExternalStorageDirectory() + "/inpaint/");
if (!f3.exists())
f3.mkdirs();
OutputStream outStream = null;
SimpleDateFormat dateFormatter;
dateFormatter = new SimpleDateFormat("MMddyyyyhhmmss", Locale.US);
String FN = Environment.getExternalStorageDirectory() + "/inpaint/" + dateFormatter.format(Calendar.getInstance().getTime()) + ".png";
File file = new File(FN);
try {
outStream = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.close();
return file.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
我们需要文件的第二个位置
全局变量
String FileName = "";
接收意图字符串数据作为文件路径以在ImageView上查看图像 此代码将在onCreate中
ImageView imgUpload = findViewById(R.id.imgUpload);
try {
if (getIntent().hasExtra("image")) {
FileName = getIntent().getStringExtra("image");
Bitmap b = BitmapFactory.decodeFile(FileName);
imgUpload.setImageBitmap(b);
}
} catch (Exception ex) {
Toast.makeText(context, "Error: " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
@Override
public void onBackPressed() {
super.onBackPressed();
try {
File file = new File(FileName);
file.delete();
} catch (Exception ex) {
Toast.makeText(context, "Error: " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
}