解决:Android base64 转 bitmap 出现黑色背景
程序员文章站
2022-06-20 21:02:16
...
一、问题场景
将 png 图片 bitmap 转为 base64,再将 base64 转为 bitmap 后对比原图,透明部分出现了黑色背景。
举个例子:
有这样一张圆角的图片,图片的四个角是透明的。
将其由 bitmap 转为 base64,再转为 bitmap 后就会出现如下的情况:
明显四个角的透明部分已经变为黑色。
二、问题原因
刚开始我也很纳闷,怎么同一张图,转为 base64 再转回图片就不一样了呢!
后来发现是由于我将一张 png 的图片转回成了一张 jpg 的图片,而 jpg 图片是不带透明通道的,如果还想带着透明通道,转回来的时候还是得转为 png。
大家在日常开发中遇到需要将 base64 与 bitmap 之间互转的需求,通常会直接在网上搜索一个工具类,却忽略了网上的一些工具类只是写死了将 bitmap 转为 jpg,而没有支持由 bitmap 转为 png。
如果你的图片没有透明部分,转为 jpg 不会有问题。如果你的原图存在透明部分,就要注意用合适的图片格式去承载这张图了!
三、解决方案
1、Kotlin 语言
object Base64Util {
/**
* bitmap 转为 base64
*
* 说明:如果发现转换后的图片存在黑边,可以将图片格式改为 png
*
* @param bitmap Bitmap?
* @param compress Int 压缩比例,范围:0-100
* @param format CompressFormat 图片格式:JPEG、PNG、WEBP、WEBP_LOSSY、WEBP_LOSSLESS
* @return String?
*/
fun bitmap2Base64(bitmap: Bitmap?, compress: Int = 100, format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG): String? {
if (bitmap == null) {
return null
}
var result: String? = null
var baos: ByteArrayOutputStream? = null
try {
try {
baos = ByteArrayOutputStream()
bitmap.compress(format, compress, baos)
baos.flush()
baos.close()
val bitmapBytes = baos.toByteArray()
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT)
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
if (baos != null) {
baos.flush()
baos.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
/**
* base64 转为 bitmap
*
* @param base64Data
* @return
*/
fun base642Bitmap(base64Data: String?): Bitmap? {
if (TextUtils.isEmpty(base64Data)) {
return null
}
return try {
val bytes: ByteArray = Base64.decode(base64Data, Base64.DEFAULT)
BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
} catch (e: Exception) {
null
}
}
}
调用:
val base64Data = Base64Util.bitmap2Base64(sourceBitmap, format = Bitmap.CompressFormat.PNG)
这样就不会丢失透明度了!
2、Java 语言
本来想着写到上面就算完了,但是为了 Java Developer 能更直观方便的阅读,也方便拿来直接用,再附上一份转为 Java 语言的代码:
public class Base64Util {
/**
* bitmap 转为 base64
*
* 说明:如果发现转换后的图片存在黑边,可以将图片格式改为 png
*
* @param bitmap Bitmap? 图片资源
* @param compress Int 压缩比例,范围:0-100
* @param format CompressFormat 图片格式:JPEG、PNG、WEBP、WEBP_LOSSY、WEBP_LOSSLESS
* @return String? base64 字符串
*/
public static String bitmap2Base64(Bitmap bitmap, int compress, Bitmap.CompressFormat format) {
if (bitmap == null) {
return null;
}
String result = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
bitmap.compress(format != null ? format : Bitmap.CompressFormat.JPEG, compress, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* base64 转为 bitmap
*
* @param base64Data
* @return
*/
public static Bitmap base642Bitmap(String base64Data) {
if (TextUtils.isEmpty(base64Data)) {
return null;
}
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}
调用方式:
Bitmap bitmap = Base64Util.bitmap2Base64(source, 100, Bitmap.CompressFormat.PNG);
搞定 !
上一篇: CPU 架构 —— ARM 架构