今天在解析和加载Base64格式的图片时遇到一个坑。
我在assets文件夹下放了一张西瓜图片的Base64文本test.txt,文本中的内容就是该图片的Base64,这样是为了在本地就模拟从后端下发了一个Base64的图片字符串。
我以流的方式先将test.txt读到字符串中,那么该超大的Base64字符串就类似于从服务端请求到的Base64图片字符串。它长下面这样,因为这里太长所以只展示一个基本结构。
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAoHBwgHBgoICAgLCgoLD......
拿到该字符串后,如果你直接调用String的startsWith()方法去匹配前缀data:image/jpeg;base64,的话实际上是匹配不到的,返回了false,因为由于编码的问题,你肉眼或者断点看到的前缀确实是
data:image/jpeg;base64,
甚至你调用String的substring()方法截取前24位的时候得到的也是
data:image/jpeg;base64,
但是问题来了,纯粹的data:image/jpeg;base64,字符串s1和大Base64字符串substring()截取前24位得到的字符串s2去进行URLEncode操作的时候得到的值是不一样的。
你会发现:
URLEncoder.encode(s1, "utf-8") 比如得到了abcdef
URLEncoder.encode(s2, "utf-8") 会得到 xxxabcdef
前面会多一些字符,这就是因为你从大Base64字符串中substring()得到的前缀其实并不是data:image/jpeg;base64,
它前面还有肉眼不可见的占位符,因此在处理Base64图片字符串去掉前缀的时候要小心(去掉前缀Android才能进一步处理与加载Bitmap,这里不再赘述原因)。正则匹配替换前缀的话得用
.*data:image/.*;base64,
而不是
data:image/.*;base64,