wake-up-neo.net

Android-Bitmap zu Base64-Zeichenfolge

Wie kann ich eine große Bitmap (mit der Kamera des Telefons aufgenommenes Foto) in eine Base64-Zeichenfolge konvertieren?

97
Pankaj Singh

verwenden Sie 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();

zum Kodieren von base64 vom Byte-Array verwenden Sie die folgende Methode

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
239
jeet

Ich habe eine schnelle Lösung. Erstellen Sie einfach eine Datei ImageUtil.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);
    }

}

Verwendungszweck:

Bitmap bitmap = ImageUtil.convert(base64String);

oder

String base64String = ImageUtil.convert(bitmap);
18
Vasilii Suricov

Das Problem mit der Antwort von jeet ist, dass Sie alle Bytes des Images in ein Bytearray laden, wodurch die App in Low-End-Geräten wahrscheinlich zum Absturz führen kann. Stattdessen würde ich das Bild zuerst in eine Datei schreiben und es mit der Apache-Klasse Base64InputStream lesen. Dann 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, arbeitet die obige Lösung stattdessen direkt mit Streams, so dass nicht alle Bytes in eine Variable geladen werden müssen. Dadurch wird der Speicherbedarf erheblich geringer und die Wahrscheinlichkeit eines Absturzes in Low-End-Geräten ist geringer. Es besteht immer noch das Problem, dass das Einfügen der Base64-Zeichenfolge selbst in eine String-Variable keine gute Idee ist, da wiederum OutOfMemory-Fehler auftreten können. Aber zumindest haben wir den Speicherbedarf um die Hälfte gesenkt, indem das Byte-Array weggelassen wurde.

Wenn Sie den Schritt "In eine Datei schreiben" überspringen möchten, müssen Sie den OutputStream in einen InputStream konvertieren. Dies ist nicht so einfach (Sie müssen PipedInputStream verwenden, aber das ist etwas komplexer als zwei Streams müssen sich immer in unterschiedlichen Threads befinden.

11
Tiago

Probieren Sie dies aus. Skalieren Sie Ihr Bild zunächst auf die erforderliche Breite und Höhe. Übergeben Sie einfach Ihre ursprüngliche Bitmap, erforderliche Breite und erforderliche Höhe mit der folgenden Methode und erhalten Sie 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 Ihr skaliertes Bitmap an die folgende Methode und erhalten Sie im Gegenzug 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 wieder in ein Bitmap-Bild:

byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
4
Ashwin

Alle diese Antworten sind ineffizient, da sie unnötigerweise zu einer Bitmap dekodieren und die Bitmap dann erneut komprimieren. Wenn Sie ein Foto unter Android aufnehmen, wird es als JPEG in der temporären Datei gespeichert, die Sie beim Folgen von der Android-Dokumente angeben.

Sie sollten diese Datei direkt in eine Base64-Zeichenfolge konvertieren. ___.

fun convertImageFileToBase64(imageFile: File): String {

    return FileInputStream(imageFile).use { inputStream ->
        ByteArrayOutputStream().use { outputStream ->
            Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
                inputStream.copyTo(base64FilterStream)
                base64FilterStream.flush()
                outputStream.toString()
            }
        }
    }
}

Als Bonus sollte Ihre Bildqualität durch die Umgehung der erneuten Komprimierung etwas verbessert werden. 

1