網站做了個隨機驗證碼圖片功能,遇到了一個奇怪的問題——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了