Yanıtlar:
Bitmap
uygular Parcelable
, böylece her zaman niyetle geçebilirsiniz:
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
ve diğer ucundan alın:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
Aslında, bir bitmap'i Parcelable olarak geçirmek "JAVA BINDER FAILURE" hatasına neden olur. Bitmap'i bir bayt dizisi olarak iletmeyi ve bir sonraki aktivitede görüntülemek için oluşturmayı deneyin.
Çözümümü burada paylaştım:
Paketleri kullanarak android etkinlikleri arasında görüntüleri (bitmapler) nasıl geçirirsiniz?
Bit eşlemin, etkinlik arasında paket halinde ayrıştırılabilir olarak geçirilmesi, Parceable (1mb) boyut sınırlaması nedeniyle iyi bir fikir değildir. Bitmap'i dahili depolama alanındaki bir dosyada saklayabilir ve saklanan bitmap'i çeşitli etkinliklerde alabilirsiniz. İşte bazı örnek kod.
Bitmap'i dahili depolama birimindeki myImage dosyasında saklamak için:
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;
}
Sonra bir sonraki aktivitede bu dosyayı myImage kodunu bir bitmap'e şu kodu kullanarak çözebilirsiniz:
//here context can be anything like getActivity() for fragment, this or MainActivity.this
Bitmap bitmap = BitmapFactory.decodeStream(context.openFileInput("myImage"));
Not Null ve ölçeklendirme bitmap'leri için çok fazla denetim önerilir.
openFileOutput
.
Görüntü çok büyükse ve depoya kaydedip yükleyemiyorsanız, yalnızca bitmap'e (alıcı etkinliğin içinde) genel statik bir referans kullanmayı düşünmelisiniz; true değerini döndürür.
Çünkü niyetin boyut sınırı vardır. Ben hizmetten yayın bit eşlem geçmek için genel statik nesne kullanın ....
public class ImageBox {
public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>();
}
servisime geç
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'ım
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
Kabul edilen cevap Bitmap
çok büyük olduğunda kilitlenir . 1 MB'lık bir sınır olduğuna inanıyorum . Bu Bitmap
, a ile temsil edilen bir JPG gibi farklı bir dosya biçiminde sıkıştırılmalıdır ByteArray
, daha sonra birIntent
.
Bu işlev, bir url'den oluşturulduktan sonra sıkıştırma zincirlendiğinden , Kotlin Coroutines kullanan ayrı bir iş parçacığında bulunur . Engellenmesi için ayrı bir iş parçacığı gerektirmektedir Yanıt vermeyen uygulama (ANR)Bitmap
Bitmap
String
Bitmap
hataları.
toBitmap()
a, Kotlin uzantı işlevi bu kütüphane gerektiren uygulama bağımlılıkları eklenecek.Bitmap
için JPG ByteArray
oluşturulduktan sonra.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(), "")))
}
}
ViewModel.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}")
}
}
})
}
ByteArray
Bir Intent
.Bu örnekte, bir den geçirilen Fragment a Service . İki Faaliyet arasında paylaşılıyorsa aynı kavram .
Fragment.kt
ContextCompat.startForegroundService(
context!!,
Intent(context, AudioService::class.java).apply {
action = CONTENT_SELECTED_ACTION
putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
})
ByteArray
geri dönün 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()
}
}
Geç olabilir ama yardımcı olabilir. İlk parçada veya aktivitede bir sınıf beyan edin ... örneğin
@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;
}
Sonra ikinci sınıfta / parçada bunu yapın ..
Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;
Umarım yardımcı olur.
Yukarıdaki çözümlerin hepsi benim için çalışmıyor, Bitmap gönderme aynı parceableByteArray
zamanda hata veriyorandroid.os.TransactionTooLargeException: data parcel size
.
Çözüm
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)
olarakIntent 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();
}
}
Bir bitmap aktarımı oluşturabilirsiniz. bunu dene....
Birinci sınıfta:
1) Oluşturun:
private static Bitmap bitmap_transfer;
2) Alıcı ve ayarlayıcı oluşturma
public static Bitmap getBitmap_transfer() {
return bitmap_transfer;
}
public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
bitmap_transfer = bitmap_transfer_param;
}
3) Görüntüyü ayarlayın:
ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());
Sonra, ikinci sınıfta:
ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));
Benim durumumda, yukarıda belirtilen yol benim için işe yaramadı. Bitmap'i her ne zaman niyetime koyduğumda 2. etkinlik başlamadı. Aynı şey bitmap'i bayt [] olarak geçtiğimde de oldu.
Bu bağlantıyı takip ettim ve bir charme gibi çalıştı ve çok hızlı:
package your.packagename
import android.graphics.Bitmap;
public class CommonResources {
public static Bitmap photoFinishBitmap = null;
}
benim 1. etkinliğimde:
Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);
ve işte 2. Etkinliğimin onCreate () yöntemi:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bitmap photo = Constants.photoFinishBitmap;
if (photo != null) {
mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
}
}
CommonResources.photoFinishBitmap
yerine kullanmanız gerektiği anlaşılıyor Constants.photoFinishBitmap
.
URI
veyaResourceID
bitmap'i iletmek her zaman daha iyidir . Tüm bitmap'i geçmek çok fazla bellek gerektirir. URL'yi iletmek çok az bellek gerektirir ve her etkinliğin bitmap'i ihtiyaç duydukları şekilde yüklemesine ve ölçeklendirmesine izin verir.