我如何可以通过一位图的对象,从一个活动到另一个
-
20-09-2019 - |
题
在我的活动,我创建了一个 Bitmap
对象然后我需要启动另一个 Activity
,
我如何可以通过这个 Bitmap
目从子活动(其中一个是要推出的)?
解决方案
Bitmap
实现Parcelable
,所以你总是可以的意图传递:
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
和检索它的另一端:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
其他提示
实际上,通过一个位图作为Parcelable将导致一个“JAVA BINDER FAILURE”错误。尝试使所述位图作为一个字节数组,并在下一个活动构建它用于显示。
我在这里分享我的解决办法:点击 你怎么传的图像(位图)之间使用束机器人活动?
Passsing位图作为在活性之间束parceable不是因为Parceable(1MB)的大小限制的一个好主意。您可以将位图存储在内部存储上的文件,并在几个活动检索存储的位图。下面是一些示例代码。
要在文件中存储的位图的 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使用下面的代码进行解码,以位图:
//here context can be anything like getActivity() for fragment, this or MainActivity.this
Bitmap bitmap = BitmapFactory.decodeStream(context.openFileInput("myImage"));
注意强>很多检查空和缩放的位图的被中省略。
如果图像过大,无法保存和加载到存储,你应该只使用一个全局静态参照位(接收活动内),这将被重置为NULL,onDestory,只要考虑“isChangingConfigurations” 返回true。
由于意图具有大小限制。 我用公共静态对象从服务做通位图来广播....
public class ImageBox {
public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>();
}
通在我的服务
private void downloadFile(final String url){
mExecutorService.submit(new Runnable() {
@Override
public void run() {
Bitmap b = BitmapFromURL.getBitmapFromURL(url);
synchronized (this){
TaskCount--;
}
Intent i = new Intent(ACTION_ON_GET_IMAGE);
ImageBox.mQ.offer(b);
sendBroadcast(i);
if(TaskCount<=0)stopSelf();
}
});
}
我的广播接收器
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
LOG.d(TAG, "BroadcastReceiver get broadcast");
String action = intent.getAction();
if (DownLoadImageService.ACTION_ON_GET_IMAGE.equals(action)) {
Bitmap b = ImageBox.mQ.poll();
if(b==null)return;
if(mListener!=null)mListener.OnGetImage(b);
}
}
};
压缩和发送 Bitmap
所接受的回答时会崩溃的 Bitmap
是太大。 我相信这是一个 1MB 限制。的 Bitmap
必须被压缩成一个不同的文件的格式,如一个 JPG 一个代表由 ByteArray
, 然后它可以安全地通过一个 Intent
.
执行情况
功能被包含在单独使用螺纹 科特林协程 因为 Bitmap
压缩相链接的后 Bitmap
创建一个网址 String
.的 Bitmap
创造需要一个单独的线以避免 没有响应(ANR) 错误。
使用的概念
- 科特林协程 注意到.
- 的 装载、内容、错误(经济) 模式是采用如下。如果感兴趣你可以了解更多关于它在 这次谈话的视频.
- 其中 用于返回的数据。我已经编制了我最喜欢的 其中 资源在 这些音符.
- 在 步骤3,
toBitmap()
是一个 科特林扩展功能 要求该图书馆将加入程序的依赖关系。
代码
1.压缩 Bitmap
要 JPG ByteArray
在已经建立。
库。kt
suspend fun bitmapToByteArray(url: String) = withContext(Dispatchers.IO) {
MutableLiveData<Lce<ContentResult.ContentBitmap>>().apply {
postValue(Lce.Loading())
postValue(Lce.Content(ContentResult.ContentBitmap(
ByteArrayOutputStream().apply {
try {
BitmapFactory.decodeStream(URL(url).openConnection().apply {
doInput = true
connect()
}.getInputStream())
} catch (e: IOException) {
postValue(Lce.Error(ContentResult.ContentBitmap(ByteArray(0), "bitmapToByteArray error or null - ${e.localizedMessage}")))
null
}?.compress(CompressFormat.JPEG, BITMAP_COMPRESSION_QUALITY, this)
}.toByteArray(), "")))
}
}
视图模型.kt
//Calls bitmapToByteArray from the Repository
private fun bitmapToByteArray(url: String) = liveData {
emitSource(switchMap(repository.bitmapToByteArray(url)) { lce ->
when (lce) {
is Lce.Loading -> liveData {}
is Lce.Content -> liveData {
emit(Event(ContentResult.ContentBitmap(lce.packet.image, lce.packet.errorMessage)))
}
is Lce.Error -> liveData {
Crashlytics.log(Log.WARN, LOG_TAG,
"bitmapToByteArray error or null - ${lce.packet.errorMessage}")
}
}
})
}
2.通过图片作为 ByteArray
通过一个 Intent
.
在这样这是通过从一个 片段 来一个 服务.这是同样的概念,如果被之间共享两个 活动.
片段。kt
ContextCompat.startForegroundService(
context!!,
Intent(context, AudioService::class.java).apply {
action = CONTENT_SELECTED_ACTION
putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
})
3.转换 ByteArray
回到 Bitmap
.
工具.kt
fun ByteArray.byteArrayToBitmap(context: Context) =
run {
BitmapFactory.decodeByteArray(this, BITMAP_OFFSET, size).run {
if (this != null) this
// In case the Bitmap loaded was empty or there is an error I have a default Bitmap to return.
else AppCompatResources.getDrawable(context, ic_coinverse_48dp)?.toBitmap()
}
}
这可能是晚了,但可以提供帮助。 在第一片段或活性做声明类...例如
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
description des = new description();
if (requestCode == PICK_IMAGE_REQUEST && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
constan.photoMap = bitmap;
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static class constan {
public static Bitmap photoMap = null;
public static String namePass = null;
}
然后在第二类/片段做..
Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;
希望它能帮助。
可以创建位图传输。尝试这种....
在所述第一类:
1)创建:
private static Bitmap bitmap_transfer;
2)创建获取和设置
public static Bitmap getBitmap_transfer() {
return bitmap_transfer;
}
public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
bitmap_transfer = bitmap_transfer_param;
}
3)设置图像:
ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());
然后,在第二类:
ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));
所有上述解决方案的对我不起作用,发送图作为 parceableByteArray
还产生的错误 android.os.TransactionTooLargeException: data parcel size
.
解决方案
- 保存在位于内部存储为:
public String saveBitmap(Bitmap bitmap) {
String fileName = "ImageName";//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;
}
- 并发送
putExtra(String)
作为
Intent intent = new Intent(ActivitySketcher.this,ActivityEditor.class);
intent.putExtra("KEY", saveBitmap(bmp));
startActivity(intent);
- 并且收到它在其他活动为:
if(getIntent() != null){
try {
src = BitmapFactory.decodeStream(openFileInput("myImage"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
在我的情况下,上述方法并没有为我工作。每当我把位图的意图,第二活动没有启动。同样的事情发生时,我通过位图的byte []。
我跟着此链接和它的工作象一个迷人和非常快速的:
package your.packagename
import android.graphics.Bitmap;
public class CommonResources {
public static Bitmap photoFinishBitmap = null;
}
在我的第一acitiviy:
Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);
和这是我的第二活动的OnCreate():
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap photo = Constants.photoFinishBitmap;
if (photo != null) {
mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
}
}