Büyük bir Bitmap'i (telefonun kamerasıyla çekilen fotoğraf) Base64 String'e nasıl dönüştürebilirim?
Büyük bir Bitmap'i (telefonun kamerasıyla çekilen fotoğraf) Base64 String'e nasıl dönüştürebilirim?
Yanıtlar:
bitmap'i bayt dizisine dönüştürmek için aşağıdaki yöntemi kullanın:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
bayt dizisinden base64 kodlamak için aşağıdaki yöntemi kullanın
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
Hızlı bir çözümüm var. Sadece bir dosya oluşturunImageUtil.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);
}
}
Kullanımı:
Bitmap bitmap = ImageUtil.convert(base64String);
veya
String base64String = ImageUtil.convert(bitmap);
Jeet'in cevabıyla ilgili sorun, görüntünün tüm baytlarını bir bayt dizisine yüklemenizdir, bu da muhtemelen uygulamanın düşük kaliteli cihazlarda çökmesine neden olacaktır. Bunun yerine, önce görüntüyü bir dosyaya yazar ve Apache'nin Base64InputStream sınıfını kullanarak okurum . Ardından, Base64 dizesini doğrudan o dosyanın InputStream öğesinden oluşturabilirsiniz. Bunun gibi görünecek:
//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();
Gördüğünüz gibi, yukarıdaki çözüm doğrudan bunun yerine akışlarla çalışır ve tüm baytları bir değişkene yükleme ihtiyacını ortadan kaldırır, bu nedenle bellek ayak izini çok daha düşük ve düşük kaliteli cihazlarda çökme olasılığını azaltır. Hala Base64 dizesinin kendisini bir String değişkenine koymanın iyi bir fikir olmaması sorunu var, çünkü yine, OutOfMemory hatalarına neden olabilir. Ama en azından bayt dizisini ortadan kaldırarak bellek tüketimini yarı yarıya azalttık.
Bir dosyaya yazma adımını atlamak istiyorsanız, OutputStream'i bir InputStream'e dönüştürmeniz gerekir ki bu çok kolay değildir ( PipedInputStream kullanmanız gerekir, ancak bu iki akış her zaman olması gerektiğinden biraz daha karmaşıktır. farklı konularda olun).
Bunu deneyin, önce görüntünüzü gerekli genişlik ve yüksekliğe ölçekleyin, orijinal bitmapinizi, gerekli genişliği ve yüksekliği aşağıdaki yönteme geçirin ve karşılığında ölçeklenmiş bitmap alın:
Örneğin: 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);
}
Şimdi ölçeklenmiş bitmap'inizi aşağıdaki yönteme iletin ve karşılığında base64 dizesini alın:
Örneğin: 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;
}
Base64 dizesinin kodunu bitmap görüntüsüne geri çözmek için:
byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
Bu yanıtların tümü, bir bitmap'e gereksiz yere kodu çözdükleri ve ardından bitmap'i yeniden sıkıştırdıkları için verimsizdir. Android'de bir fotoğraf çektiğinizde , android belgelerini takip ettiğinizde belirttiğiniz geçici dosyada jpeg olarak saklanır .
Yapmanız gereken, bu dosyayı doğrudan bir Base64 dizesine dönüştürmektir. İşte bunu kolay kopyala-yapıştır ile nasıl yapacağınız (Kotlin'de). Dahili tamponunu gerçekten boşaltmak için base64FilterStream'i kapatmanız gerektiğini unutmayın.
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()
}
}
}
}
Bonus olarak, yeniden sıkıştırmayı atlamanız nedeniyle görüntü kaliteniz biraz iyileştirilmelidir.
Artık çoğu insan Java yerine Kotlin kullandığına göre, Kotlin'de bir bitmap'i base64 dizesine dönüştürmek için kullanılan kod burada.
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)
}
Bu kodu kullanın ..
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);
}
}