Как вы передаете изображения (растровые изображения) между действиями Android с помощью пакетов? - PullRequest
49 голосов
/ 04 декабря 2010

Предположим, у меня есть действие, чтобы выбрать изображение из галереи и извлечь его в виде битовой карты, как в примере: здесь

Теперь я хочу передать этот BitMap для использования в ImageView для другого действия. Я знаю, что пакеты могут передаваться между действиями, но как мне сохранить этот BitMap в комплекте?

или я должен выбрать другой подход?

Ответы [ 9 ]

47 голосов
/ 04 декабря 2010

Я бы настоятельно рекомендовал другой подход.

Это возможно, если вы ДЕЙСТВИТЕЛЬНО хотите это сделать, но это стоит много памяти и также медленно.Это может не сработать, если у вас старый телефон и большая битмап.Вы можете просто передать его как дополнительный, например intent.putExtra("data", bitmap).Растровое изображение реализует Parcelable, так что вы можете поместить его в дополнительный.Аналогично, пакет имеет putParcelable.

Если вы хотите передать его между действиями, я бы сохранил его в файле.Это более эффективно и требует меньше работы для вас.В папке данных вы можете создавать личные файлы, используя MODE_PRIVATE, которые не доступны ни для какого другого приложения.

40 голосов
/ 25 октября 2011

Если вы передадите его как 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);
}
22 голосов
/ 08 июля 2014

В соответствии с предложением @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 в растровое изображение, используя следующий код:

Bitmap bitmap = BitmapFactory.decodeStream(context
                    .openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this

Примечание Большая часть проверки на нулевое и масштабируемое растровые изображения опущена.

5 голосов
/ 22 января 2016

Активность

Для передачи растрового изображения между Activites

Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);

А в классе деятельности

Bitmap bitmap = getIntent().getParcelableExtra("bitmap");

Фрагмент

Для передачи растрового изображения между фрагментами

SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);

Для получения внутри Второго фрагмента

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);
2 голосов
/ 04 октября 2014

в 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();
        }
2 голосов
/ 04 декабря 2010

Растровое изображение равно Parcelable , поэтому вы можете добавить его, используя метод [putExtra (String, Parcelable)] [2], но не уверен, что это лучший метод. Если данные большого размера, лучше хранить в одном месте и использовать оба вида деятельности.

[2]: http://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String, android.os.Parcelable)

1 голос
/ 27 января 2018

Вы можете передать изображение коротко, не используя такой пакет, как это Это код файла .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);

Не нужно сжимать. это все

1 голос
/ 19 января 2018

Напишите этот код, откуда вы хотите перейти к следующему действию.

    yourimageView.setDrawingCacheEnabled(true); 
    Drawable drawable = ((ImageView)view).getDrawable(); 
    Bitmap bitmap = imageView.getDrawingCache();
    Intent intent = new Intent(getBaseContext(), NextActivity.class);
    intent.putExtra("Image", imageBitmap);

В onCreate Функция NextActivity.class

Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");
1 голос
/ 30 апреля 2014

Мне пришлось немного изменить масштаб растрового изображения, чтобы он не превысил предел в 1 МБ для подшивки транзакций.Вы можете адаптировать 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;

}

После восстановления bmp в вашей следующей операции с помощью следующего кода:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_confirmBMP);
    Intent intent = getIntent();
    Bitmap bitmap = (Bitmap) intent.getParcelableExtra("Bitmap");

}

Надеюсь, мой ответ был каким-то полезнымПривет

...