Android中如何将Bitmap无损转换为Base64?
解决方案
问题根源
- 通过
Intent(MediaStore.ACTION_IMAGE_CAPTURE)启动相机后,从data.extras.get("data")获取的是系统返回的缩略图,分辨率极低,这是画质丢失的核心原因。 - 后续的
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
相关产品推荐
相关产品推荐

