В своей деятельности я создаю Bitmap
объект, а затем мне нужно запустить другой. Activity
Как я могу передать этот Bitmap
объект из под-активности (той, которая будет запущена)?
java
android
bitmap
parcelable
Майкл
источник
источник
URI
илиResourceID
растрового изображения, а не само растровое изображение. Передача всего растрового изображения требует много памяти. Передача URL-адреса требует очень мало памяти и позволяет каждому действию загружать и масштабировать растровое изображение по мере необходимости.Фактически, передача растрового изображения как Parcelable приведет к ошибке "JAVA BINDER FAILURE". Попробуйте передать растровое изображение как массив байтов и построить его для отображения в следующем действии.
Я поделился своим решением здесь:
как передавать изображения (растровые изображения) между действиями Android с помощью пакетов?
источник
Передача растрового изображения как разборного в связке между действиями не является хорошей идеей из-за ограничения размера Parceable (1 МБ). Вы можете сохранить растровое изображение в файле во внутренней памяти и извлечь сохраненное растровое изображение в нескольких действиях. Вот пример кода.
Чтобы сохранить растровое изображение в файле 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 и масштабирование растровых изображений опущены.
источник
openFileOutput
.Если изображение слишком велико и вы не можете сохранить и загрузить его в хранилище, вам следует подумать об использовании просто глобальной статической ссылки на растровое изображение (внутри принимающей активности), которая будет сброшена на null в onDestory, только если "isChangingConfigurations" возвращает истину.
источник
Потому что у намерения есть ограничение на размер. Я использую общедоступный статический объект для передачи растрового изображения из службы в трансляцию ....
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(); } }); }
Мой BroadcastReceiver
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
окажется слишком большим. Я считаю, что это ограничение в 1 МБ . ОнBitmap
должен быть сжат в другой формат файла, такой как JPG, представленный символом aByteArray
, затем его можно безопасно передать черезIntent
.Реализация
Функция содержится в отдельном потоке с использованием Kotlin Coroutines, потому что
Bitmap
сжатие выполняется после того,Bitmap
как создается из URL-адресаString
. ДляBitmap
создания требуется отдельный поток, чтобы приложение не отвечало (ANR). ошибок « .Используемые концепции
toBitmap()
является функция расширения Котлин требует эту библиотеку , чтобы добавить к зависимостям приложений.Код
1. Сожмите
Bitmap
в JPGByteArray
после того, как он был создан.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}") } } }) }
2. Передайте изображение как
ByteArray
черезIntent
.В этом примере он передается из фрагмента в службу . То же самое и при совместном использовании двух Activity .
Fragment.kt
ContextCompat.startForegroundService( context!!, Intent(context, AudioService::class.java).apply { action = CONTENT_SELECTED_ACTION putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image) })
3. Преобразовать
ByteArray
обратно в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() } }
источник
Возможно, уже поздно, но может помочь. В первом фрагменте или действии объявите класс ... например
@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;
Надеюсь, это поможет.
источник
Все вышеперечисленные решения не работают для меня, отправка растрового изображения
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(); } }
источник
Вы можете создать перенос растрового изображения. попробуй это....
В первом классе:
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 image2 = (ImageView) view.findViewById(R.id.img2); imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));
источник
В моем случае способ, упомянутый выше, у меня не сработал. Каждый раз, когда я помещал растровое изображение в намерение, второе действие не запускалось. То же самое произошло, когда я передал растровое изображение как byte [].
Я перешел по этой ссылке, и она сработала как шарм и очень быстро:
package your.packagename import android.graphics.Bitmap; public class CommonResources { public static Bitmap photoFinishBitmap = null; }
в моей 1-й деятельности:
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)); } }
источник
CommonResources.photoFinishBitmap
вместоConstants.photoFinishBitmap
.