如何将图像转换为Base64字符串?

161

如何将一张图片(最大200KB)转换成 Base64 字符串?

我需要知道在 Android 中如何实现这个功能,因为我需要在我的主要应用程序中添加上传图片到远程服务器的功能,并将它们作为字符串放入数据库的一行中。

我已经在 Google 和 Stack Overflow 上搜索了很久,但是没有找到易于理解的示例代码。虽然我找到了一些示例代码,但它们并没有讲述如何将图片转换成字符串。所以我需要将它们转换成字符串后通过 JSON 上传到远程服务器。

18个回答

368

您可以使用Base64 Android类:

String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

不过,你需要将图像转换为字节数组。这里有一个例子:

Bitmap bm = BitmapFactory.decodeFile("/path/to/image.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();

* 更新 *

如果您正在使用旧的SDK库(因为您希望它可以在旧版本操作系统的手机上运行),则您将不会拥有Base64类包(因为它只是在API级别8(也称为2.2版本)中才发布)。

请参考这篇文章以获取解决方法:

如何在Android上进行base64编码和解码


哦,该死,“Base64适用于Api级别8,即Android 2.2”......我的应用程序必须与所有版本的Android兼容...1.5、1.6、2.1等等...我能做些什么来在Android 1.5(Api级别3)上使用Base64吗? - NullPointerException
啊,是的,你说得对。这篇文章应该解决那个问题:http://androidcodemonkey.blogspot.com/2010/03/how-to-base64-encode-decode-android.html。我也在答案中更新了它。 - xil3
4
替换后我的工作如下:将字节数组图像用Base64编码,使用以下代码:String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT); - PakitoV
4
有人意识到这种方法会对文件进行无意义的重新压缩吗?为什么会有那么多赞?Chandra Sekhar的回答是最有效的。 - ElYeante
1
ElYeante - 你说得完全正确,那是更有效的做法。 - xil3
显示剩余12条评论

111

除了使用 Bitmap,您还可以通过简单的 InputStream 来完成此操作。虽然我不确定,但我认为这样会更加高效。

InputStream inputStream = new FileInputStream(fileName); // You can get an inputStream using any I/O API
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();

try {
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
}
catch (IOException e) {
    e.printStackTrace();
}

bytes = output.toByteArray();
String encodedString = Base64.encodeToString(bytes, Base64.DEFAULT);

4
当然,这样更有效率;只需将文件转换为其base64表示形式,避免了对图像进行完全无意义的重新压缩。 - ElYeante
这里的fileName是文件路径还是实际文件名?请不要忘记标记我 :) 谢谢。 - Rakeeb Rajbhandari
2
@user2247689 当您尝试访问文件时,显然必须提供包括文件名在内的完整路径。如果文件位于源程序所在的相同路径中,则仅需要文件名即可。 - Chandra Sekhar
2
一个问题,这里的“8192”代表什么?是文件大小还是其他什么? - Devesh Khandelwal
1
这段代码不起作用,浪费了我很多时间来解决问题。 - Ramkesh Yadav
显示剩余3条评论

8
如果您需要在JSON中使用Base64,请查看Jackson:它在低级别(JsonParser、JsonGenerator)和数据绑定级别上都有对二进制数据读写作为Base64的明确支持。因此,您只需拥有具有byte[]属性的POJOs,编码/解码就会自动处理。
而且,效率也相当高,如果这很重要的话。

1
对我来说太难了,我的技能水平很低,我在谷歌上查找了一下,没有找到简单的例子...也许如果您能给我像xil3这样的代码示例,我就能理解它。 - NullPointerException

6

以下是 Kotlin 中的编码和解码代码:

 fun encode(imageUri: Uri): String {
    val input = activity.getContentResolver().openInputStream(imageUri)
    val image = BitmapFactory.decodeStream(input , null, null)

    // Encode image to base64 string
    val baos = ByteArrayOutputStream()
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    var imageBytes = baos.toByteArray()
    val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
    return imageString
}

fun decode(imageString: String) {

    // Decode base64 string to image
    val imageBytes = Base64.decode(imageString, Base64.DEFAULT)
    val decodedImage = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)

    imageview.setImageBitmap(decodedImage)
}

你不应该关闭任何打开的输入流吗? - behelit

5
// Put the image file path into this method
public static String getFileToByte(String filePath){
    Bitmap bmp = null;
    ByteArrayOutputStream bos = null;
    byte[] bt = null;
    String encodeString = null;
    try{
        bmp = BitmapFactory.decodeFile(filePath);
        bos = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        bt = bos.toByteArray();
        encodeString = Base64.encodeToString(bt, Base64.DEFAULT);
    }
    catch (Exception e){
      e.printStackTrace();
    }
    return encodeString;
}

3

这段代码在我的项目中运行完美:

profile_image.buildDrawingCache();
Bitmap bmap = profile_image.getDrawingCache();
String encodedImageData = getEncoded64ImageStringFromBitmap(bmap);


public String getEncoded64ImageStringFromBitmap(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 70, stream);
    byte[] byteFormat = stream.toByteArray();

    // Get the Base64 string
    String imgString = Base64.encodeToString(byteFormat, Base64.NO_WRAP);

    return imgString;
}

3
如果您正在使用Android进行此操作,则可以使用从React Native代码库复制的帮助程序:
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.util.Base64;
import android.util.Base64OutputStream;
import android.util.Log;

// You probably don't want to do this with large files
// (will allocate a large string and can cause an OOM crash).
private String readFileAsBase64String(String path) {
  try {
    InputStream is = new FileInputStream(path);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
    byte[] buffer = new byte[8192];
    int bytesRead;
    try {
      while ((bytesRead = is.read(buffer)) > -1) {
        b64os.write(buffer, 0, bytesRead);
      }
      return baos.toString();
    } catch (IOException e) {
      Log.e(TAG, "Cannot read file " + path, e);
      // Or throw if you prefer
      return "";
    } finally {
      closeQuietly(is);
      closeQuietly(b64os); // This also closes baos
    }
  } catch (FileNotFoundException e) {
    Log.e(TAG, "File not found " + path, e);
    // Or throw if you prefer
    return "";
  }
}

private static void closeQuietly(Closeable closeable) {
  try {
    closeable.close();
  } catch (IOException e) {
  }
}

2
(将分配大字符串并可能导致OOM崩溃)那么在这种情况下,解决方案是什么? - Ibrahim Disouki

1

在 Kotlin 中,还有一种更简单的写法:

fun imageBase64(filepath: String): String {
    FileInputStream(filepath).use {
        val bytes = it.readBytes()
        return Base64.encodeToString(bytes, Base64.DEFAULT)
    }
}

1

Kotlin版本:

fun File.toBase64(): String? {
 val result: String?
 inputStream().use { inputStream ->
    val sourceBytes = inputStream.readBytes()
    result = Base64.encodeToString(sourceBytes, Base64.DEFAULT)
 }

 return result
}

1

在Android中将图像转换为Base64字符串:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接