网站做了个随机验证码图片功能,遇到了一个奇怪的问题——Base64字符集转图片乱码问题,问题描述如下
1.用java画笔将随机验证码绘制成图片
2.再将图片的二进制代码转换成Base64字符集,返回给前端,
以上步骤,在本地window环境下,随机验证码图片生成base64字符传送到前端,能完美解析出来,但是部署到生产环境(centos)上,则解析base64字符得到的是一张乱码图片。
经过初步分析,应该是系统环境差异造成的,
1.一开始以为是字符编码和解码的问题,但base64本身是用ascii字符集,本身不存在编码集不对的问题。所以排除字符集解码和编码不对的问题。
2.接着,检查了下生成的base64字符的长度,2207个字符,远没达到string的最大字符长度。
3.那么有没有可能是绘制的图片本身就是乱码的,base64字符还原出的图片是没问题的。因此仔细看下绘制随机验证码的代码
public static String outputRandomImageDataUrl(String randomString) throws IOException { int width = 100; int height = 30; Color color = getRandomColor(); Color reverse = getReverseColor(color); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16)); g.setColor(color); g.fillRect(0, 0, width, height); g.setColor(reverse); g.drawString(randomString, 18, 20); for (int i = 0, n = random.nextInt(100); i < n; i++) { g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1); } return DATAURL_PREFIX + ImageConvertUtils.imageConvertBase64(bi); }
然后发现这句
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
字体是微软雅黑字体,linux系统已办是肯定是不会有这个字体的,于是本人在生产环境检查了下系统字符集,果然没有,找到问题所在,那么就很好解决了。
1.程序代码中选择一个生产环境已有的字体。
2.安装程序指定的字体。
本人是采用第二种方式,安装了微软雅黑字体后果然ok了