Bagaimana cara mengonversi Bitmap besar (foto yang diambil dengan kamera ponsel) menjadi String Base64?
Bagaimana cara mengonversi Bitmap besar (foto yang diambil dengan kamera ponsel) menjadi String Base64?
Jawaban:
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);
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);
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).
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);
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.
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)
}
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);
}
}