在做项目的时候需要动态把个人二维码嵌入到活动背景图的指定位置,由于我们的图片都是存在阿里云的oss上的,调研之后,感觉使用阿里云的oss的WaterMark来实现听方便的,但是在拼接图片路径的时候,需要将要嵌入的二维码图片转为base64编码。
生成的路径如下:
https://xxxxxxx.com/activity/shareImage/a54ce090-99b8-464d-8cce-9ce9e819252d.jpg?x-oss-process=image/watermark,image_YWN0aXZpdHkvcXJDb2RlLzIwMjQtMDIvMTAwXzQ3My5wbmc/eC1vc3MtcHJvY2Vzcz1pbWFnZS9y
ZXNpemUscF81MA==,g_se,x_50,y_50
访问的时候返回错误
关键错误信息 The value: eC1vc3MtcHJvY2Vzcz1pbWFnZS9y of parameter: process is invalid
eC1vc3MtcHJvY2Vzcz1pbWFnZS9y 这一段是二维码图片base64之后的一部分数据。
查看之后 eC1vc3MtcHJvY2Vzcz1pbWFnZS9y 前面有个 / 。这个 / 被放在url中就会被解析为一层路径,后来查了资料发现
由于base64中包含【+】、【/】字符,而这2个字符在不同场景下会产生歧义,因此,针对不同的应用场景又分别研制了Base64的各种变种,为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本;(即去掉上面这2个字符)
与URL相关的变种
当base64用于URL编码时,鉴于base64里面自带的【+】、【/】,URL编码器会对这2个字符变成“%XX”形式,而在SQL中“%”是作为模糊匹配的,因此,需要在入库之前需要对“%XX”进行转换;
为了解决这种场景下的base64应用问题,而出现了针对URL编码器的base64变种:
①在末尾填充'='号;
②将标准Base64中的“+”和“/”分别改成了“-”和“_”,避免在URL编解码和数据库存储时所要作的
与正则表达式相关的变种
base64里面自带的【+】、【/】在正则表达式中有特殊的含义,因此,需要有一种针对正则表达式的变种:
①将Base64的“+”和“/”改成了“!”和“-”;
其他变种
还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name);
由于我这里是属于url , 我将 / 替换为 _
https://xxxxxxxx.com/activity/shareImage/a54ce090-99b8-464d-8cce-9ce9e819252d.jpg?x-oss-process=image/watermark,image_YWN0aXZpdHkvcXJDb2RlLzIwMjQtMDIvMTAwXzQ3My5wbmc_eC1vc3MtcHJvY2Vzcz1pbWFnZS9y
ZXNpemUscF81MA==,g_se,x_50,y_50
凭感觉是因为有换行符 \r 的问题,看了一下路劲确实在有地方换行了
手动去掉换行,图片正常访问了
https://xxxxxxxx.com/activity/shareImage/a54ce090-99b8-464d-8cce-9ce9e819252d.jpg?x-oss-process=image/watermark,image_YWN0aXZpdHkvcXJDb2RlLzIwMjQtMDIvMTAwXzQ3My5wbmc_eC1vc3MtcHJvY2Vzcz1pbWFnZS9yZXNpemUscF81MA==,g_se,x_50,y_50
二维码成功的嵌入到了图片上了
最终代码实现
String base64WaterMarkPath = EncryptUtil.base64Encrypt( waterMarkPath.getBytes(StandardCharsets.UTF_8)).replaceAll("\r|\n" , "");
base64WaterMarkPath = base64WaterMarkPath.replaceAll("/" , "_");