Frage

In meiner Tätigkeit erstelle ich eine Bitmap Objekt und dann brauche ich zum starten eines anderen Activity, Wie kann ich diese übergeben Bitmap Objekt aus der sub-Aktivität (die eine, die ist gehen zu gestartet werden)?

War es hilfreich?

Lösung

Bitmap Geräte Parcelable, so konnte man immer es passiert, mit der Absicht:

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

und rufen sie am anderen Ende:

Intent intent = getIntent(); 
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");

Andere Tipps

Eigentlich wird eine Bitmap als Parcel vorbei führen zu einem „JAVA BINDER FAILURE“ Fehlern. Versuchen Sie das Bestehen die Bitmap als Byte-Array und Gebäude es für die Anzeige in der nächsten Aktivität.

ich meine Lösung hier geteilt:
wie geben Sie Bilder ( Bitmaps) zwischen android-Aktivitäten Bündel mit?

Passsing Bitmap als parceable in Bündel zwischen Aktivität ist keine gute Idee, weil die Größenbeschränkung von Parceable (1MB). Sie können die Bitmap in einer Datei im internen Speicher speichern und die gespeicherte Bitmap in mehreren Aktivitäten abzurufen. Hier ist ein Beispielcode.

Zum Speichern von Bitmap in einer Datei myImage in internen Speichern:

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

Dann in der nächsten Aktivität können Sie diese Datei myImage in einem Bitmap dekodieren folgenden Code:

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

Hinweis Eine Menge für null Überprüfung und Bitmap Skalierung wird ommited.

Wenn das Bild zu groß ist und man kann es auf die Speicher nicht speichern und laden, sollten Sie nur einen globalen statischen Verweis auf die Bitmap mit (innerhalb der Aufnahmeaktivität), die wieder auf null auf onDestory sein wird, nur dann, wenn "isChangingConfigurations" true zurück.

Da Intent Größenbeschränkung. Ich benutze öffentliches statisches Objekt Pass Bitmap aus dem Dienst zu Sendung zu tun ....

public class ImageBox {
    public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>(); 
}

Pass in meinem Dienst

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

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

Komprimieren und Versenden Bitmap

Die akzeptierte Antwort wird Abstürzen, wenn die Bitmap zu groß. Ich glaube, es ist ein 1 MB Grenze.Die Bitmap werden muss, komprimiert in ein anderes Dateiformat wie ein JPG vertreten durch ByteArray, dann kann es sicher passiert über ein Intent.

Umsetzung

Die Funktion ist, die in einem separaten thread verwenden Kotlin Coroutinen da die Bitmap Kompression ist angekettet, nachdem die Bitmap erstellt von einer url String.Die Bitmap Erstellung erfordert einen separaten thread, um zu vermeiden, Anwendung Nicht mehr Reagiert (ANR) Fehler.

Konzepte

  • Kotlin Coroutinen notes.
  • Die Be -, Content -, Fehler - (LCE) Muster unten verwendet wird.Bei Interesse können Sie mehr dazu erfahren Sie in dieser Vortrag und video.
  • LiveData wird verwendet, um die Daten zurückzugeben.Das ich zusammengestellt habe meine Lieblings LiveData Ressource diese Hinweise.
  • In Schritt 3, toBitmap() ist ein Kotlin-Erweiterung Funktion die Forderung, dass-Bibliothek Hinzugefügt werden die app-Abhängigkeiten.

Code

1.Komprimieren Bitmap zu JPG ByteArray nachdem es erstellt wurde.

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.Pass-Bild als ByteArray über eine Intent.

In diesem Beispiel ist es der übergang von Fragment zu einem Service.Es ist das gleiche Konzept, wenn geteilt zwischen zwei Aktivitäten.

Fragment.kt

ContextCompat.startForegroundService(
    context!!,
    Intent(context, AudioService::class.java).apply {
        action = CONTENT_SELECTED_ACTION
        putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
    })

3.Konvertieren ByteArray zurück 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()
        }
    }

Es könnte sein, spät, aber helfen kann. Auf dem ersten Fragmente oder Aktivität tun, um eine Klasse deklariert ... zum Beispiel

   @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;
}

Dann auf der zweiten Klasse / Fragment tun, um diese ..

Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;

Hope es hilft.

Sie können eine Bitmap-Übertragung erstellen. try this ....

In der ersten Klasse:

1) Erstellen Sie:

private static Bitmap bitmap_transfer;

2) Erstellen Sie Getter und Setter

public static Bitmap getBitmap_transfer() {
    return bitmap_transfer;
}

public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
    bitmap_transfer = bitmap_transfer_param;
}

3) Stellen Sie das Bild:

ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());

Dann in der zweiten Klasse:

ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));

Alle oben genannten Lösungen nicht funktioniert für mich, Senden Bitmap als parceableByteArray auch Fehler android.os.TransactionTooLargeException: data parcel size erzeugt.

Lösung

  1. Saved die Bitmap in internen Speicher wie:
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;
    }
  1. und sendet in putExtra(String) als
Intent intent = new Intent(ActivitySketcher.this,ActivityEditor.class);
intent.putExtra("KEY", saveBitmap(bmp));
startActivity(intent);
  1. und empfängt sie in einer anderen Aktivität als:
if(getIntent() != null){
  try {
           src = BitmapFactory.decodeStream(openFileInput("myImage"));
       } catch (FileNotFoundException e) {
            e.printStackTrace();
      }

 }


In meinem Fall erwähnte die Möglichkeit, oben nicht für mich gearbeitet. Jedes Mal, wenn ich die Bitmap in der Absicht setzte, hat die zweite Aktivität nicht gestartet werden. Das gleiche passiert, wenn ich die Bitmap als byte [] übergeben.

Ich folgte diesem Link und es funktionierte wie ein Charme und sehr schnell:

package your.packagename

import android.graphics.Bitmap;

public class CommonResources { 
      public static Bitmap photoFinishBitmap = null;
}

in meinem ersten acitiviy:

Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);

und hier ist die onCreate () meiner zweiten Aktivität:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bitmap photo = Constants.photoFinishBitmap;
    if (photo != null) {
        mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top