Как вы передаете изображения (растровые изображения) между действиями андроида с помощью пакетов?

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

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

или есть другой подход, который я должен принять?

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

Как было предложено @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

Примечание Много проверок для растрового изображения с нулевым и масштабируемым значениями.

Ответ 4

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

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

Ответ 5

активность

Чтобы передать растровое изображение между Activites

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

И в классе Activity

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");

Перенос большого растрового изображения (сжатие bitmap)

Если вы получаете неудачную транзакцию связующего, это означает, что вы превышаете буфер транзакции связующего, передавая большой элемент из одного действия в другой.

Таким образом, в этом случае вам нужно сжать битмап в виде массива байтов, а затем распаковать его в другой активности, например

В FirstActivity

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);

И в SecondActivity

byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

Ответ 6

в 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();
        }

Ответ 7

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

}

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

Ответ 8

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

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

В onCreate Function из NextActivity.class

Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");

Ответ 9

Вы можете передать изображение короче, не используя пучок, подобный этому. Это код отправителя.class file

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);

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