Android 位图到 Base64 字符串
Posted
技术标签:
【中文标题】Android 位图到 Base64 字符串【英文标题】:Android Bitmap to Base64 String 【发布时间】:2012-03-02 16:51:33 【问题描述】:如何将大型位图(用手机相机拍摄的照片)转换为 Base64 字符串?
【问题讨论】:
您想如何对图像进行编码? 你问错问题了。使用手机相机拍摄的照片存储为 jpeg,而不是位图。您只需要将 jpeg 解码为位图即可显示它。如果您按照下面我的回答进行操作,将会减少 OutOfMemory 错误和不必要的处理。 【参考方案1】:使用以下方法将位图转换为字节数组:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
使用以下方法从字节数组编码base64
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
【讨论】:
感谢您的解决方案,我使用了相同的代码,但我的编码字符串有 ... 最后我认为它没有完全转换,所以请告诉我为什么在 Base 64 字符串的末尾是点( ...).. @Pankaj 嗨,你能告诉我你是如何解决这个问题的吗,我的编码字符串中面临同样的问题有 3 个点(...)你能帮忙解决这个问题吗 @SachinGurnani - 它显示 ... 因为 logcat 显示有限的字符串长度,然后被截断。这就是为什么。 这应该在 asynctask 中完成吗?或者在主线程中这样做可以吗? 如果您不想在 Base64 字符串中使用\n
,您可能想使用 Base64.NO_WRAP
。【参考方案2】:
我有快速的解决方案。只需创建一个文件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);
【讨论】:
这个base64Str.substring(base64Str.indexOf(",") + 1)
在做什么?我没有看到我的字符串有“,”。
嘿,当我看到base64字符串的输出时,这是用断线渲染,我需要如何解决?因为我需要让它进入内联模式【参考方案3】:
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,但这有点复杂,因为这两个流必须始终位于不同的线程中)。
【讨论】:
这里的编码是什么?【参考方案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);
【讨论】:
我找到了问题的答案:我的 base64 编码位图出现错误“非法字符 a”,使用 Base64.NO_WRAP 解决了这个问题【参考方案5】:所有这些答案都是低效的,因为它们不必要地解码为位图,然后重新压缩位图。当您在 Android 上拍照时,它会以 jpeg 格式存储在您关注 the android docs 时指定的临时文件中。
您应该直接将该文件转换为 Base64 字符串。 以下是如何通过简单的复制粘贴(在 Kotlin 中)来做到这一点。请注意,您必须关闭 base64FilterStream 才能真正刷新其内部缓冲区。
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()
另外,由于绕过了重新压缩,您的图像质量应该会略有提高。
【讨论】:
【参考方案6】:现在大多数人使用 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)
【讨论】:
【参考方案7】:使用此代码..
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);
【讨论】:
以上是关于Android 位图到 Base64 字符串的主要内容,如果未能解决你的问题,请参考以下文章