Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android位图到Base64字符串_Android_Bitmap_Base64_Android Bitmap - Fatal编程技术网

Android位图到Base64字符串

Android位图到Base64字符串,android,bitmap,base64,android-bitmap,Android,Bitmap,Base64,Android Bitmap,如何将大位图(使用手机摄像头拍摄)转换为Base64字符串?使用以下方法将位图转换为字节数组: ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); byte[] byteArray = byteArrayOutputStream .toByteArray

如何将大位图(使用手机摄像头拍摄)转换为Base64字符串?

使用以下方法将位图转换为字节数组:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
要从字节数组编码base64,请使用以下方法

String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);

jeet回答的问题是,你将图像的所有字节加载到一个字节数组中,这可能会使低端设备中的应用程序崩溃。相反,我会先将图像写入一个文件,然后使用Apache的类读取它。然后可以直接从该文件的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字符串本身放入字符串变量不是一个好主意,因为它可能会再次导致OutOfMemory错误。但至少我们通过消除字节数组将内存消耗减少了一半


如果您想跳过“写入文件”步骤,则必须将OutputStream转换为InputStream,这并不是那么简单(您必须使用,但这有点复杂,因为这两个流必须始终位于不同的线程中)。

我有一个快速解决方案。只需创建一个文件
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);


尝试此操作,首先将图像缩放到所需的宽度和高度,只需将原始位图、所需的宽度和所需的高度传递到以下方法,然后返回缩放位图:

例如:位图缩放位图=getScaledBitmap(originalBitmap,250350)

现在,只需将缩放的位图传递给以下方法,并返回base64字符串:

例如:String base64String=getBase64String(缩放位图)

要将base64字符串解码回位图图像,请执行以下操作:

byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);

所有这些答案都是无效的,因为它们不必要地解码为位图,然后重新压缩位图。当你在Android上拍照时,它会以jpeg格式存储在你跟随时指定的临时文件中

您应该做的是直接将该文件转换为Base64字符串。 下面是如何在easy copy paste(在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()
            }
        }
    }
}
作为奖励,由于绕过了重新压缩,您的图像质量应该会略有提高

使用此代码

导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.util.Base64;
导入java.io.ByteArrayOutputStream;
公共类ImageUtil
{ 
公共静态位图转换(字符串base64Str)引发IllegalArgumentException
{ 
字节[]decodedBytes=Base64.decode(base64Str.substring(base64Str.indexOf(“,”)+1),Base64.DEFAULT);
返回BitmapFactory.decodeByteArray(decodedBytes,0,decodedBytes.length);
} 
公共静态字符串转换(位图)
{ 
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
compress(bitmap.CompressFormat.PNG,100,outputStream);
返回Base64.encodeToString(outputStream.toByteArray(),Base64.DEFAULT);
}
}

现在大多数人使用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)
    }

你想如何对图像进行编码?你问错了问题。使用手机摄像头拍摄的照片存储为jpeg格式,而不是位图。只需将jpeg解码为位图即可显示。如果您按照下面的答案操作,您将减少OutOfMemory错误和不必要的处理。感谢您的解决方案,我使用了相同的代码,但我的编码字符串。。。最后,我认为它没有被完全转换,所以请告诉我为什么在64进制字符串的末尾是点(…)。@Pankaj嗨,你能告诉我如何解决这个问题吗,我在我的编码字符串中面临同样的问题有3个点(…),你能帮我解决吗that@SachinGurnani-它显示。。。因为logcat显示有限的字符串长度,并且在这之后它被截断。这就是为什么。谢谢你的回复。我已经在同一天解决了这个问题。这应该在异步任务中完成吗?或者在主线程中这样做可以吗?这里的编码是什么?这是什么
base64Str.substring(base64Str.indexOf(“,”)+1)
在做什么?我看不到我的字符串有“,”。嘿,当我看到base64字符串中的输出时,这是使用换行符进行渲染,我需要如何解决它?因为我需要用内联模式
byte[] decodedByteArray = Base64.decode(base64String, Base64.NO_WRAP);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedByteArray, 0, decodedString.length);
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()
            }
        }
    }
}
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)
    }