如何将大型位图(使用手机相机拍摄的照片)转换为Base64字符串?
答案 0 :(得分:247)
使用以下方法将位图转换为字节数组:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
使用以下方法
从字节数组编码base64String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
答案 1 :(得分:20)
我有快速解决方案。只需创建一个文件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);
}
}
用法:
Bitmap bitmap = ImageUtil.convert(base64String);
或
String base64String = ImageUtil.convert(bitmap);
答案 2 :(得分:12)
jeet的答案问题是你将图像的所有字节加载到字节数组中,这可能会使低端设备中的应用程序崩溃。相反,我首先将图像写入文件并使用Apache的Base64InputStream类读取它。然后,您可以直接从该文件的InputStream创建Base64字符串。它看起来像这样:
//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();
正如您所看到的,上述解决方案直接与流相关,无需将所有字节加载到变量中,从而使内存占用更低,并且不太可能在低端设备中崩溃。仍然存在将Base64字符串本身放入String变量的问题并不是一个好主意,因为它可能会导致OutOfMemory错误。但至少我们通过消除字节数组将内存消耗减少了一半。
如果要跳过“写入文件”步骤,则必须将OutputStream转换为InputStream,这不是那么简单(必须使用PipedInputStream但是更多一点复杂的,因为两个流必须始终在不同的线程中。)
答案 3 :(得分:4)
试试这个,首先将图像缩放到所需的宽度和高度,只需将原始位图,所需宽度和所需高度传递给以下方法,然后获得缩放位图:
例如:位图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);
}
现在只需将缩放后的位图传递给以下方法并获取base64字符串:
例如: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字符串解码回位图图像:
byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
答案 4 :(得分:1)
所有这些答案都是无效的,因为它们不必要地解码为位图,然后重新压缩位图。在Android上拍照时,照片会以jpeg格式存储在您按照the android docs进行操作时指定的临时文件中。
您应该做的就是直接将该文件转换为Base64字符串。 这是通过简单的复制粘贴操作(在Kotlin中)的方法。
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()
}
}
}
}
作为一项奖励,由于绕过了重新压缩,因此图像质量应稍有提高。
答案 5 :(得分:1)
现在大多数人使用Kotlin而不是Java,这是Kotlin中用于将位图转换为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)
}
答案 6 :(得分:-1)
使用此代码。
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);
}
}