Comment convertir un grand Bitmap (photo prise avec l'appareil photo du téléphone) en une chaîne Base64?
Comment convertir un grand Bitmap (photo prise avec l'appareil photo du téléphone) en une chaîne Base64?
Réponses:
utilisez la méthode suivante pour convertir le bitmap en tableau d'octets:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
pour encoder base64 à partir d'un tableau d'octets, utilisez la méthode suivante
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
J'ai une solution rapide. Créez simplement un fichierImageUtil.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);
}
}
Usage:
Bitmap bitmap = ImageUtil.convert(base64String);
ou
String base64String = ImageUtil.convert(bitmap);
Le problème avec la réponse de jeet est que vous chargez tous les octets de l'image dans un tableau d'octets, ce qui plantera probablement l'application dans les appareils bas de gamme. Au lieu de cela, j'écrirais d'abord l'image dans un fichier et je la lisais à l'aide de la classe Base64InputStream d'Apache . Ensuite, vous pouvez créer la chaîne Base64 directement à partir du InputStream de ce fichier. Il ressemblera à ceci:
//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();
Comme vous pouvez le voir, la solution ci-dessus fonctionne directement avec les flux à la place, évitant d'avoir à charger tous les octets dans une variable, rendant ainsi l'empreinte mémoire beaucoup plus faible et moins susceptible de planter dans les appareils bas de gamme. Il y a toujours le problème que placer la chaîne Base64 elle-même dans une variable String n'est pas une bonne idée, car, encore une fois, cela peut provoquer des erreurs OutOfMemory. Mais au moins, nous avons réduit de moitié la consommation de mémoire en éliminant le tableau d'octets.
Si vous souhaitez sauter l'étape d'écriture dans un fichier, vous devez convertir OutputStream en InputStream, ce qui n'est pas si simple à faire (vous devez utiliser PipedInputStream mais c'est un peu plus complexe car les deux flux doivent toujours être dans différents threads).
Essayez ceci, mettez d'abord votre image à l'échelle à la largeur et à la hauteur requises, passez simplement votre bitmap d'origine, la largeur requise et la hauteur requise à la méthode suivante et obtenez une image bitmap mise à l'échelle en retour:
Par exemple: 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);
}
Maintenant, passez simplement votre bitmap mis à l'échelle à la méthode suivante et obtenez la chaîne base64 en retour:
Par exemple: 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;
}
Pour décoder la chaîne base64 en image bitmap:
byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
Toutes ces réponses sont inefficaces car elles décodent inutilement un bitmap, puis recompressent le bitmap. Lorsque vous prenez une photo sur Android, elle est stockée au format jpeg dans le fichier temporaire que vous spécifiez lorsque vous suivez les documents Android .
Ce que vous devez faire est de convertir directement ce fichier en une chaîne Base64. Voici comment faire cela en simple copier-coller (dans Kotlin). Notez que vous devez fermer base64FilterStream pour vraiment vider sa mémoire tampon interne.
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()
}
}
}
}
En prime, la qualité de votre image devrait être légèrement améliorée, en raison du contournement de la recompression.
Maintenant que la plupart des gens utilisent Kotlin au lieu de Java, voici le code de Kotlin pour convertir un bitmap en une chaîne 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)
}
Utilisez ce 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);
}
}