You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何将Bitmap无损转换为Base64?

解决方案

问题根源

  1. 通过Intent(MediaStore.ACTION_IMAGE_CAPTURE)启动相机后,从data.extras.get("data")获取的是系统返回的缩略图,分辨率极低,这是画质丢失的核心原因。
  2. 后续的encodeImage方法又主动将图片缩放至宽度150,并以70%的JPEG质量压缩,进一步加剧了画质损失。

修复步骤

1. 改为获取相机拍摄的原图

通过指定图片保存路径,让相机直接将原图保存到指定位置,而非只返回缩略图:

private lateinit var imageFile: File

ivPersonImageA.setOnClickListener {
    // 创建保存原图的文件
    val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    imageFile = File.createTempFile(
        "JPEG_${System.currentTimeMillis()}_",
        ".jpg",
        storageDir
    )
    val imageUri = FileProvider.getUriForFile(
        this,
        "${packageName}.fileprovider", // 需在Manifest中配置FileProvider
        imageFile
    )
    val mIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
    }
    startActivityForResult(mIntent, PERSON_CODE)
}

2. 修改onActivityResult获取原图

不再从data.extras拿缩略图,而是直接读取指定路径的原图文件:

@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == PERSON_CODE && resultCode == RESULT_OK) {
        // 读取原图文件转为Bitmap
        val imageBitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
        personAvImageA.setImageBitmap(imageBitmap)
        mPesrsonBase64 = encodeImage(imageBitmap)
        Log.e("mPersonBase64", mPesrsonBase64)
    }
}

3. 调整encodeImage方法(按需调整压缩策略)

如果不需要强制缩放,可去掉主动缩放逻辑,或根据实际需求调整压缩质量:

private fun encodeImage(bitmap: Bitmap): String {
    // 去掉主动缩放,保留原图尺寸(若需缩放可根据实际需求调整比例)
    val byteArrayOutputStream = ByteArrayOutputStream()
    // 调整JPEG压缩质量,建议85-100之间(100为无损)
    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream)
    val bytes = byteArrayOutputStream.toByteArray()
    return Base64.encodeToString(bytes, Base64.DEFAULT) // 用DEFAULT替代CRLF,避免换行符干扰
}

4. 配置FileProvider(必须步骤)

在AndroidManifest.xml中添加FileProvider配置,确保相机能正常写入文件:

<application>
    ...
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

然后在res/xml目录下创建file_paths.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="my_images" path="Pictures" />
</paths>

额外说明

  • 如果需要对原图进行尺寸压缩(比如控制上传文件大小),建议根据原图分辨率计算合适的缩放比例,而非固定宽度150,避免过度压缩。
  • JPEG格式本身是有损压缩,若追求无损可考虑使用Bitmap.CompressFormat.PNG,但文件体积会更大。

内容的提问来源于stack exchange,提问作者Ansar Ali Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:32:35