Android 13一加/OPPO/Realme 5G设备Bitmap压缩报错求助
问题分析与解决方法
针对一加、OPPO、Realme(尤其是RMX3741机型)搭载Android 13的5G设备中图片压缩报错的问题,结合代码和系统特性,给出以下分析和解决方案:
可能触发原因
- 部分ColorOS/Realme UI(Android 13版本)对带透明通道的Bitmap执行JPEG压缩时存在兼容性问题:JPEG格式本身不支持透明,部分厂商系统未做兼容处理,直接抛出异常。
- RMX3741机型的系统压缩库存在特定Bug,对ARGB_8888等格式的Bitmap处理逻辑异常。
针对性解决方法
方法1:处理Bitmap透明通道
如果你的Bitmap包含透明区域,先转换为不支持透明的格式再压缩,避免系统报错:
@RequiresApi(Build.VERSION_CODES.O) fun bitmapToBase64(bitmap: Bitmap): String { val targetBitmap = if (bitmap.hasAlpha()) { // 创建无透明通道的Bitmap,用白色填充背景避免透明区域变黑 Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.RGB_565).apply { val canvas = Canvas(this) canvas.drawColor(Color.WHITE) canvas.drawBitmap(bitmap, 0f, 0f, null) } } else { bitmap } val byteArrayOutputStream = ByteArrayOutputStream() targetBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) // 回收临时Bitmap,避免内存泄漏 if (targetBitmap != bitmap) { targetBitmap.recycle() } val byteArray: ByteArray = byteArrayOutputStream.toByteArray() return String(Base64.getEncoder().encode(byteArray)) }
方法2:切换为PNG压缩格式(业务允许时)
PNG格式支持透明且兼容性更好,若业务场景可接受更大的文件体积,直接替换压缩格式:
@RequiresApi(Build.VERSION_CODES.O) fun bitmapToBase64(bitmap: Bitmap): String { val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream) val byteArray: ByteArray = byteArrayOutputStream.toByteArray() return String(Base64.getEncoder().encode(byteArray)) }
方法3:异常捕获+降级处理
针对特定机型的压缩异常,添加捕获逻辑,自动切换为PNG压缩:
@RequiresApi(Build.VERSION_CODES.O) fun bitmapToBase64(bitmap: Bitmap): String { val byteArrayOutputStream = ByteArrayOutputStream() return try { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray())) } catch (e: Exception) { // JPEG压缩失败,降级为PNG byteArrayOutputStream.reset() bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream) String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray())) } }
方法4:前置Bitmap状态检查
避免因Bitmap已被回收等内存状态异常导致的压缩失败,添加前置检查:
@RequiresApi(Build.VERSION_CODES.O) fun bitmapToBase64(bitmap: Bitmap): String { require(!bitmap.isRecycled) { "Bitmap has been recycled" } val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) val byteArray: ByteArray = byteArrayOutputStream.toByteArray() return String(Base64.getEncoder().encode(byteArray)) }
内容的提问来源于stack exchange,提问作者SYED ABUTHAHIR
相关产品推荐
相关产品推荐

