Wie konvertiere ich eine große Bitmap (mit der Kamera des Telefons aufgenommenes Foto) in eine Base64-Zeichenfolge?
Wie konvertiere ich eine große Bitmap (mit der Kamera des Telefons aufgenommenes Foto) in eine Base64-Zeichenfolge?
Antworten:
Verwenden Sie die folgende Methode, um die Bitmap in ein Byte-Array zu konvertieren:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
Verwenden Sie die folgende Methode, um base64 aus dem Byte-Array zu codieren
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
Ich habe eine schnelle Lösung. Erstellen Sie einfach eine DateiImageUtil.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
public class ImageUtil
{
public static Bitmap convert(String base64Str) throws IllegalArgumentException
{
byte[] decodedBytes = Base64.decode(
base64Str.substring(base64Str.indexOf(",") + 1),
Base64.DEFAULT
);
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}
public static String convert(Bitmap bitmap)
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
}
}
Verwendung:
Bitmap bitmap = ImageUtil.convert(base64String);
oder
String base64String = ImageUtil.convert(bitmap);
Das Problem mit der Antwort von jeet ist, dass Sie alle Bytes des Bildes in ein Byte-Array laden, wodurch die App auf Low-End-Geräten wahrscheinlich abstürzt. Stattdessen würde ich zuerst das Bild in eine Datei schreiben und es mit der Base64InputStream- Klasse von Apache lesen . Anschließend können Sie die Base64-Zeichenfolge direkt aus dem InputStream dieser Datei erstellen. Es wird so aussehen:
//Don't forget the manifest permission to write files
final FileOutputStream fos = new FileOutputStream(yourFileHere);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
final InputStream is = new Base64InputStream( new FileInputStream(yourFileHere) );
//Now that we have the InputStream, we can read it and put it into the String
final StringWriter writer = new StringWriter();
IOUtils.copy(is , writer, encoding);
final String yourBase64String = writer.toString();
Wie Sie sehen können, funktioniert die obige Lösung stattdessen direkt mit Streams, sodass nicht alle Bytes in eine Variable geladen werden müssen, wodurch der Speicherbedarf erheblich verringert wird und die Wahrscheinlichkeit eines Absturzes bei Low-End-Geräten geringer ist. Es besteht immer noch das Problem, dass das Einfügen des Base64-Strings selbst in eine String-Variable keine gute Idee ist, da dies wiederum zu OutOfMemory-Fehlern führen kann. Aber zumindest haben wir den Speicherverbrauch halbiert, indem wir das Byte-Array eliminiert haben.
Wenn Sie den Schritt zum Schreiben in eine Datei überspringen möchten, müssen Sie den OutputStream in einen InputStream konvertieren, was nicht so einfach ist (Sie müssen PipedInputStream verwenden , dies ist jedoch etwas komplexer, da die beiden Streams immer erforderlich sind in verschiedenen Threads sein).
Versuchen Sie dies, skalieren Sie zuerst Ihr Bild auf die erforderliche Breite und Höhe, übergeben Sie einfach Ihre ursprüngliche Bitmap, die erforderliche Breite und die erforderliche Höhe an die folgende Methode und erhalten Sie im Gegenzug eine skalierte Bitmap:
Zum Beispiel: Bitmap scaledBitmap = getScaledBitmap (originalBitmap, 250, 350);
private Bitmap getScaledBitmap(Bitmap b, int reqWidth, int reqHeight)
{
int bWidth = b.getWidth();
int bHeight = b.getHeight();
int nWidth = bWidth;
int nHeight = bHeight;
if(nWidth > reqWidth)
{
int ratio = bWidth / reqWidth;
if(ratio > 0)
{
nWidth = reqWidth;
nHeight = bHeight / ratio;
}
}
if(nHeight > reqHeight)
{
int ratio = bHeight / reqHeight;
if(ratio > 0)
{
nHeight = reqHeight;
nWidth = bWidth / ratio;
}
}
return Bitmap.createScaledBitmap(b, nWidth, nHeight, true);
}
Übergeben Sie nun einfach Ihre skalierte Bitmap an die folgende Methode und erhalten Sie im Gegenzug den base64-String:
Zum Beispiel: String base64String = getBase64String (scaledBitmap);
private String getBase64String(Bitmap bitmap)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String base64String = Base64.encodeToString(imageBytes, Base64.NO_WRAP);
return base64String;
}
So dekodieren Sie die base64-Zeichenfolge zurück in das Bitmap-Image:
byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
Alle diese Antworten sind ineffizient, da sie unnötigerweise in eine Bitmap dekodiert und dann die Bitmap erneut komprimiert werden. Wenn Sie ein Foto unter Android aufnehmen, wird es als JPEG in der temporären Datei gespeichert, die Sie angeben, wenn Sie den Android-Dokumenten folgen .
Sie sollten diese Datei direkt in eine Base64-Zeichenfolge konvertieren. Hier erfahren Sie, wie Sie dies in einfachem Kopieren und Einfügen (in Kotlin) tun. Beachten Sie, dass Sie den base64FilterStream schließen müssen, um den internen Puffer wirklich zu leeren.
fun convertImageFileToBase64(imageFile: File): String {
return FileInputStream(imageFile).use { inputStream ->
ByteArrayOutputStream().use { outputStream ->
Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
inputStream.copyTo(base64FilterStream)
base64FilterStream.close()
outputStream.toString()
}
}
}
}
Als Bonus sollte Ihre Bildqualität leicht verbessert werden, da die erneute Komprimierung umgangen wird.
Da die meisten Benutzer Kotlin anstelle von Java verwenden, finden Sie hier den Code in Kotlin zum Konvertieren einer Bitmap in eine base64-Zeichenfolge.
import java.io.ByteArrayOutputStream
private fun encodeImage(bm: Bitmap): String? {
val baos = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val b = baos.toByteArray()
return Base64.encodeToString(b, Base64.DEFAULT)
}
Verwenden Sie diesen Code ..
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
public class ImageUtil
{
public static Bitmap convert(String base64Str) throws IllegalArgumentException
{
byte[] decodedBytes = Base64.decode( base64Str.substring(base64Str.indexOf(",") + 1), Base64.DEFAULT );
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}
public static String convert(Bitmap bitmap)
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
}
}