Android Bitmap ke String Base64

128

Bagaimana cara mengonversi Bitmap besar (foto yang diambil dengan kamera ponsel) menjadi String Base64?

Pankaj Singh
sumber
Bagaimana Anda ingin menyandikan gambar?
Ted Hopp
Anda menanyakan pertanyaan yang salah. Foto yang diambil dengan kamera ponsel disimpan sebagai jpeg, bukan bitmap. Anda hanya perlu mendekode jpeg menjadi bitmap untuk menampilkannya. Anda akan memiliki lebih sedikit kesalahan OutOfMemory dan pemrosesan yang tidak perlu jika Anda mengikuti jawaban saya di bawah ini.
Carson Holzheimer

Jawaban:

301

gunakan metode berikut untuk mengubah bitmap menjadi array byte:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();

untuk menyandikan base64 dari larik byte menggunakan metode berikut

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
jeet
sumber
Terima kasih atas solusinya, saya telah menggunakan kode yang sama tetapi string yang disandikan telah ... pada akhirnya dan saya pikir itu tidak diubah sepenuhnya jadi tolong beri tahu saya mengapa pada akhir string Basis 64 adalah titik-titik (...) ..
Pankaj Singh
@Pankaj Hai, bisakah Anda memberi tahu saya bagaimana Anda menyelesaikan masalah itu, saya menghadapi masalah yang sama dalam string yang dikodekan memiliki 3 titik (...) bisakah Anda membantu mengatasinya
Sachin Gurnani
5
@SachinGurnani - ini menunjukkan ... karena logcat menampilkan String lenth terbatas dan setelah itu terpotong. itu sebabnya.
Pankaj Singh
Terima kasih atas tanggapan Anda Pankaj. Saya telah membahas masalah ini pada hari yang sama
Sachin Gurnani
1
haruskah ini dilakukan dalam asynctask? atau apakah tidak masalah melakukan ini di utas utama?
n3wb
28

Saya punya solusi cepat. Buat saja fileImageUtil.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);
    }

}

Pemakaian:

Bitmap bitmap = ImageUtil.convert(base64String);

atau

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

Masalah dengan jawaban jeet adalah Anda memuat semua byte gambar ke dalam array byte, yang kemungkinan akan merusak aplikasi di perangkat kelas bawah. Sebagai gantinya, saya akan menulis gambar ke file dan membacanya menggunakan kelas Base64InputStream Apache . Kemudian Anda dapat membuat string Base64 langsung dari InputStream file itu. Ini akan terlihat seperti ini:

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

Seperti yang Anda lihat, solusi di atas bekerja langsung dengan aliran, menghindari kebutuhan untuk memuat semua byte ke dalam variabel, oleh karena itu membuat jejak memori jauh lebih rendah dan kecil kemungkinannya untuk mogok di perangkat kelas bawah. Masih ada masalah bahwa meletakkan string Base64 itu sendiri ke dalam variabel String bukanlah ide yang baik, karena, sekali lagi, ini dapat menyebabkan kesalahan OutOfMemory. Tetapi setidaknya kita telah memotong konsumsi memori hingga setengahnya dengan menghilangkan array byte.

Jika Anda ingin melewatkan langkah tulis-ke-file, Anda harus mengonversi OutputStream ke InputStream, yang tidak begitu mudah untuk dilakukan (Anda harus menggunakan PipedInputStream tetapi itu sedikit lebih rumit karena kedua aliran harus selalu berada di utas yang berbeda).

Tiago
sumber
2
Apa pengkodean di sini?
Animesh Mangla
5

Coba ini, pertama ubah skala gambar Anda ke lebar dan tinggi yang diperlukan, cukup teruskan bitmap asli Anda, lebar yang diperlukan, dan tinggi yang diperlukan ke metode berikut dan dapatkan bitmap yang diskalakan sebagai gantinya:

Misalnya: 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);
}

Sekarang teruskan bitmap skala Anda ke metode berikut dan dapatkan string base64 sebagai gantinya:

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

Untuk mendekode string base64 kembali ke gambar bitmap:

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

Semua jawaban ini tidak efisien karena mereka mendekode ke bitmap dan kemudian mengompresi ulang bitmap tersebut. Saat Anda mengambil foto di Android, foto itu disimpan sebagai jpeg di file temp yang Anda tentukan saat mengikuti dokumen android .

Apa yang harus Anda lakukan adalah langsung mengonversi file itu ke string Base64. Berikut adalah cara melakukannya dengan copy-paste mudah (di Kotlin). Perhatikan, Anda harus menutup base64FilterStream untuk benar-benar membersihkan buffer internalnya.

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

Sebagai bonus, kualitas gambar Anda harus sedikit ditingkatkan, karena melewati proses kompresi ulang.

Carson Holzheimer
sumber
1

Sekarang kebanyakan orang menggunakan Kotlin dan bukan Java, berikut adalah kode di Kotlin untuk mengonversi bitmap menjadi string base64.

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)
    }
Reddy Tintaya
sumber
-2

Gunakan kode ini ..

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);
    }
}
Pengembang Acme
sumber