Jawaban:
Bitmapmengimplementasikan Parcelable, sehingga Anda selalu bisa melewatinya dengan maksud:
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
dan mengambilnya di ujung yang lain:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
Sebenarnya, melewatkan bitmap sebagai Parcelable akan menghasilkan kesalahan "JAVA BINDER FAILURE". Coba lewati bitmap sebagai array byte dan buat untuk ditampilkan di aktivitas selanjutnya.
Saya membagikan solusi saya di sini:
bagaimana Anda mengirimkan gambar (bitmap) antara aktivitas Android menggunakan bundel?
Melewati bitmap sebagai parceable dalam bundel di antara aktivitas bukanlah ide yang baik karena batasan ukuran Parceable (1mb). Anda dapat menyimpan bitmap dalam file di penyimpanan internal dan mengambil bitmap yang disimpan dalam beberapa aktivitas. Ini beberapa contoh kode.
Untuk menyimpan bitmap dalam file myImage di penyimpanan internal:
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;
}
Kemudian pada aktivitas selanjutnya Anda dapat mendekode file myImage ke bitmap menggunakan kode berikut:
//here context can be anything like getActivity() for fragment, this or MainActivity.this
Bitmap bitmap = BitmapFactory.decodeStream(context.openFileInput("myImage"));
Catatan Banyak memeriksa null dan menskalakan bitmap dihentikan.
openFileOutput.
Jika gambar terlalu besar dan Anda tidak dapat menyimpan & memuatnya ke penyimpanan, Anda harus mempertimbangkan hanya menggunakan referensi statis global ke bitmap (di dalam aktivitas penerima), yang akan diatur ulang ke nol pada onDestory, hanya jika "isChangingConfigurations" mengembalikan true.
Karena Intent memiliki batas ukuran. Saya menggunakan objek statis publik untuk melakukan pass bitmap dari layanan ke siaran ....
public class ImageBox {
public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>();
}
lulus dalam layanan saya
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();
}
});
}
BroadcastReceiver saya
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);
}
}
};
BitmapJawaban yang diterima akan macet ketika Bitmapterlalu besar. Saya percaya ini adalah batas 1MB . The Bitmapharus dikompresi ke dalam format file yang berbeda seperti JPG diwakili oleh ByteArray, maka dapat dengan aman melewati melaluiIntent .
Fungsi ini terkandung dalam utas terpisah menggunakan Kotlin Coroutines karena Bitmapkompresi dirantai setelah Bitmapdibuat dari url String. The Bitmappenciptaan membutuhkan thread terpisah untuk menghindari Aplikasi Tidak Menanggapi (PPA) kesalahan.
toBitmap()adalah fungsi ekstensi Kotlin yang membutuhkan pustaka yang akan ditambahkan ke dependensi aplikasi.Bitmapke JPG ByteArray setelah itu dibuat.Repository.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(), "")))
}
}
LihatModel.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}")
}
}
})
}
ByteArraymelalui Intent.Dalam sampel ini, ini diteruskan dari Fragmen ke Layanan . Itu adalah konsep yang sama jika dibagikan di antara dua Kegiatan .
Fragment.kt
ContextCompat.startForegroundService(
context!!,
Intent(context, AudioService::class.java).apply {
action = CONTENT_SELECTED_ACTION
putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
})
ByteArraykembali ke Bitmap.Utils.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()
}
}
Mungkin terlambat tetapi bisa membantu. Pada fragmen atau aktivitas pertama, deklarasikan sebuah kelas ... misalnya
@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;
}
Kemudian pada kelas kedua / fragmen lakukan ini ..
Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;
Semoga ini bisa membantu.
Semua solusi di atas tidak bekerja untuk saya, Mengirim bitmap parceableByteArrayjuga menghasilkan kesalahan android.os.TransactionTooLargeException: data parcel size.
Larutan
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)sebagaiIntent 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();
}
}
Anda dapat membuat transfer bitmap. coba ini....
Di kelas pertama:
1) Buat:
private static Bitmap bitmap_transfer;
2) Buat pengambil dan penyetel
public static Bitmap getBitmap_transfer() {
return bitmap_transfer;
}
public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
bitmap_transfer = bitmap_transfer_param;
}
3) Atur gambar:
ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());
Kemudian, di kelas kedua:
ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));
Dalam kasus saya, cara yang disebutkan di atas tidak berhasil untuk saya. Setiap kali saya menaruh bitmap dalam maksud, aktivitas ke-2 tidak dimulai. Hal yang sama terjadi ketika saya melewati bitmap sebagai byte [].
Saya mengikuti tautan ini dan itu bekerja seperti pesona dan sangat cepat:
package your.packagename
import android.graphics.Bitmap;
public class CommonResources {
public static Bitmap photoFinishBitmap = null;
}
dalam kegiatan pertama saya:
Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);
dan ini adalah onCreate () dari Aktivitas ke-2 saya:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap photo = Constants.photoFinishBitmap;
if (photo != null) {
mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
}
}
CommonResources.photoFinishBitmapbukan Constants.photoFinishBitmap.
URIatauResourceIDbitmap dan bukan bitmap itu sendiri. Melewati seluruh bitmap membutuhkan banyak memori. Melewati URL membutuhkan sedikit memori dan memungkinkan setiap aktivitas memuat dan menskalakan bitmap sesuai kebutuhan.