zxing二维码生成工具类
生活随笔
收集整理的這篇文章主要介紹了
zxing二维码生成工具类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
圖片生成工具生成
1.支持多中形式的圖片,二維碼,條形碼
2.支持一張圖片多個二維碼
3.支持二維碼圖片上加logo
4.支持圖片頭部底部添加文字描述
public class ZxingEncoderUtil {private static final String CHARSET = "utf-8";private static final String FORMAT = "JPG";private static Font font = null;/*** 二維碼生成,支持一張圖上多個二維碼,支持圖片添加字體(上下位置),支持二維碼中間加logo,** @param content* @param qrWidth* @param qrHeight* @param barcodeFormat* @param logoPath* @param multiImgs* @param options key image_top_1 *** 表示圖片要加的內容* @return*/public static byte[] createImage(String content, int qrWidth, int qrHeight, BarcodeFormat barcodeFormat, String logoPath, Boolean multiImgs, Map<String, String> options) {//每個圖片之間的間隔int gap = 0;//每行的行距int lineHeight = 0;//字符串的高度int strHeight = 15;List<String> contents = new ArrayList<>();try {HashMap<EncodeHintType, Object> hints = new HashMap<>();if (StringUtils.isNotBlank(logoPath)) {hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //容錯等級 L、M、Q、H 其中 L 為最低, H 為最高} else {hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //容錯等級 L、M、Q、H 其中 L 為最低, H 為最高 }hints.put(EncodeHintType.CHARACTER_SET, CHARSET); // 字符編碼hints.put(EncodeHintType.MARGIN, 0); // 二維碼與圖片邊距if (multiImgs != null && multiImgs) {String[] str = content.split(",");contents = Arrays.asList(str);gap = 15;} else {contents.add(content);}//去重ArrayList<String> result = new ArrayList<>();for (String item : contents) {if (Collections.frequency(result, item) < 1) result.add(item);}Map<String, SortedMap<String, String>> addImage = addOnImage(options);SortedMap<String, String> topMap = addImage.get("top");SortedMap<String, String> bottomMap = addImage.get("bottom");//行距if (topMap != null && !topMap.isEmpty() || bottomMap != null && !bottomMap.isEmpty()) {lineHeight = 5;}//畫布的寬,高int bWidth = qrWidth;int bHeight = qrHeight + gap + lineHeight * 2;//如果是條形碼,需要增加源字符串在畫布上if (barcodeFormat.equals(BarcodeFormat.CODE_128)) {bHeight += strHeight;}//如果要加頭文字,需要加上頭部的高度if (topMap != null && !topMap.isEmpty()) {bHeight += strHeight * topMap.size();}//如果要加上底部描述,需要加上底部高度if (bottomMap != null && !bottomMap.isEmpty()) {bHeight += strHeight * bottomMap.size();}//整個畫布的高度bHeight = bHeight * result.size() - gap;//設置畫布BufferedImage source = new BufferedImage(bWidth, bHeight, BufferedImage.TYPE_INT_RGB);Graphics2D graph = source.createGraphics();//設置背景顏色 graph.setBackground(Color.WHITE);graph.clearRect(0, 0, bWidth, bHeight);if (font == null) {FileInputStream inputStream = new FileInputStream(new File(ZxingEncoderUtil.class.getResource("/font/msyh.ttf").getFile()));font = Font.createFont(Font.TRUETYPE_FONT, inputStream).deriveFont(Font.BOLD, 14f);inputStream.close();}graph.setFont(font);graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);graph.setColor(Color.BLACK);//下一次起始Y位置int nextPosY = 0;//匯總一次的高度int singleHeight;int topHeight;for (String item : result) {singleHeight = 0;topHeight = 0;BufferedImage image = printImage(item, barcodeFormat, qrWidth, qrHeight, logoPath, hints);//畫圖片上部分if (topMap != null && !topMap.isEmpty()) {for (SortedMap.Entry<String, String> entry : topMap.entrySet()) {int strWidth = graph.getFontMetrics().stringWidth(entry.getValue());int strX = (image.getWidth(null) - strWidth) / 2;int strY = strHeight * Integer.valueOf(entry.getKey()) + nextPosY;graph.drawString(entry.getValue(), strX, strY);}topHeight = strHeight * topMap.size();}//圖片坐標int imageX = 0;int imageY = topHeight + lineHeight + nextPosY;//畫圖片graph.drawImage(image, imageX, imageY, image.getWidth(null), image.getHeight(null), null);singleHeight += topHeight + lineHeight + image.getHeight(null);if (barcodeFormat.equals(BarcodeFormat.CODE_128)) {int strWidth = graph.getFontMetrics().stringWidth(item);int strX = (image.getWidth(null) - strWidth) / 2;int strY = imageY + strHeight + image.getHeight(null);graph.drawString(item, strX, strY);singleHeight += strHeight;}//畫圖片下部分if (bottomMap != null && !bottomMap.isEmpty()) {for (SortedMap.Entry<String, String> entry : bottomMap.entrySet()) {int strWidth = graph.getFontMetrics().stringWidth(entry.getValue());int strX = (image.getWidth(null) - strWidth) / 2;int strY = strHeight * Integer.valueOf(entry.getKey()) + nextPosY + singleHeight;graph.drawString(entry.getValue(), strX, strY);}singleHeight += strHeight * bottomMap.size();}//設置下次畫圖的位置int i = result.indexOf(item);nextPosY = (singleHeight + gap) * (i + 1);}graph.setStroke(new BasicStroke(3f));graph.dispose();return imageIO(source);} catch (Exception e) {}return null;}/*** BufferedImage 轉字節流** @param source* @return*/private static byte[] imageIO(BufferedImage source) {try {ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(source, "jpg", os);return os.toByteArray();} catch (Exception ex) {return null;}}/*** 插入LOGO** @param source* @param logoPath* @throws Exception*/private static void insertImage(BufferedImage source, String logoPath) throws Exception {File file = new File(ZxingEncoderUtil.class.getResource(String.format("/image/%s", logoPath)).getFile());if (!file.exists()) {throw new Exception("logo file not found.");}Image src = ImageIO.read(file);int width = src.getWidth(null);int height = src.getHeight(null);// 插入LOGOGraphics2D graph = source.createGraphics();int x = (source.getWidth() - width) / 2;int y = (source.getHeight() - height) / 2;graph.drawImage(src, x, y, width, height, null);Shape shape = new RoundRectangle2D.Float(x, y, width, height, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}/*** zxing工具生成BufferedImage** @param content* @param barcodeFormat* @param qrWidth* @param qrHeight* @param logoPath* @param hints* @return* @throws Exception*/private static BufferedImage printImage(String content, BarcodeFormat barcodeFormat, int qrWidth, int qrHeight, String logoPath, HashMap<EncodeHintType, Object> hints) throws Exception {BitMatrix bitMatrix = new MultiFormatWriter().encode(content, barcodeFormat, qrWidth, qrHeight, hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (StringUtils.isNotBlank(logoPath)) {insertImage(image, logoPath);}return image;}/*** 獲取位置參數** @param options key image_AA_BB value *** AA位置(top,bottom) BB 排序* @return*/private static Map<String, SortedMap<String, String>> addOnImage(Map<String, String> options) {Map<String, SortedMap<String, String>> result = Collections.synchronizedMap(new HashMap<String, SortedMap<String, String>>());SortedMap<String, String> topMap = Collections.synchronizedSortedMap(new TreeMap<String, String>());SortedMap<String, String> bottomMap = Collections.synchronizedSortedMap(new TreeMap<String, String>());try {if (options != null && !options.isEmpty())for (Map.Entry<String, String> entry : options.entrySet()) {if (StringUtils.isNotBlank(entry.getValue())) {//topif (entry.getKey().startsWith("image_top")) {topMap.put(entry.getKey().replace("image_top_", ""), entry.getValue());}//bottomif (entry.getKey().startsWith("image_bottom")) {bottomMap.put(entry.getKey().replace("image_bottom_", ""), entry.getValue());}}}} catch (Exception e) {}result.put("top", topMap);result.put("bottom", bottomMap);return result;} }?
在開發這個工具的途中遇到問題:在本地win系統上圖片drawString時,中文顯示正常,但是到linux系統時,中文就顯示不出來,顯示的是方框,造成這種問題是由于操作系統不支持中文字體導致,最終最佳的解決方案是,下載需要的字體,放根目錄,通過讀取文件的方式獲得字體,
java.awt.Font類方法createFont獲取文件的方式獲得字體,從而改變drawString畫中文不異常,此解決方案不必改動linux系統字體轉載于:https://www.cnblogs.com/spring-Ganoder/p/7449361.html
總結
以上是生活随笔為你收集整理的zxing二维码生成工具类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转) 使用vivado创建工程 1
- 下一篇: 不使用java内置函数,将String字