Introduce zxing’s mature QR code generation interface to generate standard QR code files, and add relevant text descriptions to the QR codes through the java graphics and image processing API. As needed, you can synthesize Add relevant background to the final image. An example is shown in the figure below:
1. Let’s take a bitmap first. The core code for generating a QR code image is as follows
/** * 定义二维码的参数 */ HashMap<EncodeHintType, Object> hints = new HashMap(); //指定字符编码为“utf-8” hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //指定二维码的纠错等级为中级 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //设置图片的边距 hints.put(EncodeHintType.MARGIN, 1); /** * 生成二维码 */ try { BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT, hints); Path file = new File(filePath).toPath(); MatrixToImageWriter.writeToPath(bitMatrix, format, file); } catch (Exception e) { log.error("二维码生成出错:/permitDownload: error", e); }
2. Add text to the QR code
/** * 给二维码下方添加说明文字 * * @param image 原二维码 * @param topText 顶部说明文字 * @param downText 底部说明文字 * @return 带说明文字的二维码 */ private static BufferedImage addNote(BufferedImage image, String topText, String downText) { Image src = image.getScaledInstance(QRCODE_WIDTH, QRCODE_HEIGHT, Image.SCALE_DEFAULT); BufferedImage tag = new BufferedImage(QRCODE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = tag.createGraphics();//设置文字 g2.setColor(Color.BLACK); g2.setBackground(Color.WHITE); g2.clearRect(0,0,QRCODE_WIDTH, IMAGE_HEIGHT); //设置顶部文本并计算坐标 // 保证操作系统包含“宋体”字体,如果没有上传字体至JAVA_HOME/jre/lib/fonts下 FontMetrics fm = getFontByWidth(new Font("宋体", Font.PLAIN, DEFAULT_FONT_SIZE), topText, g2); //文字的宽度 int fontWidth = fm.stringWidth(topText); //文字高度 int fontHeight = fm.getHeight(); /** * 顶部添加文字并居中 */ g2.drawString(topText, (QRCODE_WIDTH - fontWidth) / 2, (TEXT_DEFAULT_HEIGHT - fontHeight) / 2 + fm.getFont().getSize()); /** * 绘制二维码 */ g2.drawImage(src, 0, TEXT_DEFAULT_HEIGHT, null); // 设置底部文字字体并计算坐标 // 保证操作系统包含“宋体”字体,如果没有上传字体至JAVA_HOME/jre/lib/fonts下 fm = getFontByWidth(new Font("宋体", Font.PLAIN, DEFAULT_FONT_SIZE), downText, g2); //文字的宽度 fontWidth = fm.stringWidth(downText); //文字高度 fontHeight = fm.getHeight(); /** * 添加底部文字 */ g2.drawString(downText, (QRCODE_WIDTH - fontWidth) / 2, QRCODE_HEIGHT + TEXT_DEFAULT_HEIGHT+(TEXT_DEFAULT_HEIGHT - fontHeight) / 2 + fm.getFont().getSize()); g2.dispose(); image = tag; image.flush(); return image; }
Knowledge point: The length of the text at the bottom will change, and the current design only puts one line of text , so the text size will be dynamically changed according to the number of words in a reasonable range (not too small to be recognized), using the FontMetrics object, this point will be helpful to most students
3. Dynamic Modify the font and size
/** * 根据文字长度改变文字大小 * * @param font 默认字体 * @param note 文字内容 * @param g2 图像画布 * @return 处理后的字体封装 */ private static FontMetrics getFontByWidth(Font font, String note, Graphics2D g2) { FontMetrics fm = g2.getFontMetrics(font); int textWidth = fm.stringWidth(note);//文字的宽度 if (textWidth > QRCODE_WIDTH) { int fontSize = (int) ((TEMP_PARAM / textWidth) * font.getSize()); font = new Font(font.getName(), font.getStyle(), fontSize); } g2.setFont(font); return g2.getFontMetrics(font); }
4. The last step is to combine the blue background image and the QR code image, and that’s it.
The first step: Create the canvas, you need to set the width and height of the canvas, the unit should be pixels
BufferedImage tag = new BufferedImage(QRCODE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
The second step Step: Create the graphics object Graphics2D on the canvas. You can set information such as background, foreground, border, width and other information based on your understanding of the image knowledge points
Graphics2D g2 = tag.createGraphics();//设置文字
Step 3: Synthesize the picture, the order of adding the pictures in the process , picture size, and coordinate position will affect the final presentation effect. If the final effect does not meet the design requirements, adjusting these three parameters will definitely help
Image src = image.getScaledInstance(QRCODE_WIDTH, QRCODE_HEIGHT, Image.SCALE_DEFAULT); ... /** * 绘制二维码 */ g2.drawImage(src, 0, TEXT_DEFAULT_HEIGHT, null);
Step 4: Generate the final new picture
/** * 给二维码图片添加背景图片 * * @param qrPic 二维码 * @param backImage 背景图片 */ private static void createNewPng(File qrPic, BufferedImage backImage) { try { if (!qrPic.isFile()) { log.error("二维码临时路径不存在!"); } /** * 读取背景图片,并构建绘图对象--画布 */ Graphics2D g = backImage.createGraphics(); /** * 读取二维码图片 */ BufferedImage qrcodeImage = ImageIO.read(qrPic); //开始绘制图片 g.drawImage(qrcodeImage, 48, 120, qrcodeImage.getWidth(), qrcodeImage.getHeight(), null); g.dispose(); ImageIO.write(backImage, "png", qrPic); } catch (Exception e) { log.error("绘制二维码出错!"); } }
The second picture is generated in the same process as the first picture, just change the order in [2. Add text to the QR code] from top, middle and bottom to left and right
The pixels and size of the background image need to match the QR code, otherwise the ratio between the QR code and the background will be seriously out of balance or the QR code display will be incomplete
QR code adds text garbled development environment (windows), test environment (centos server version). There are no problems in local development and testing. After packaging and deploying to the server, all Chinese characters appear garbled (various transcoding, font settings, debugging for a long time), and the problem still has not changed. Finally, I suddenly had an idea and suspected that it was a system font problem. I checked the font information of the test environment (centos) and indeed there was no "Songti". I set it to the system's own or default font, but the problem still persists. Finally, copy the font from the development system (c:\windows\fonts\simsun.ttc) to the test system (JAVA_HOME/jre/libs/fonts) and restart the application, and the problem is perfectly solved. It is a bit troublesome to prepare fonts for system installation and deployment. I don’t know if there is a better way. Fonts include logical fonts and physical fonts. Let’s do this for now.
The background image loading problem project is a springboot project. The background image is stored in the resources folder. No exceptions were found in local development and testing. The background image cannot be found after being packaged and deployed to the server. The original code is as follows
String backFilePath = "template/down.png"; ClassPathResource resource = new ClassPathResource(backFilePath); File file = resource.getFile();
I have tried all the ways to load images on the Internet, but it has no effect. Finally, I changed it to the input stream, and the image synthesis is normal. The code is as follows
/** * 必须通过流方式,否则不同操作系统无法拿到背景图片信息 */ String backFilePath = "template/down.png"; ClassPathResource resource = new ClassPathResource(backFilePath); BufferedImage bi = ImageIO.read(resource.getInputStream());
The above is the detailed content of How to synthesize complex QR code images with java zxing. For more information, please follow other related articles on the PHP Chinese website!