使用 Qrcode 生成中间带 logo 的二维码!
可以自由定义生成的二维码中间是否带 logo !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | package com.controller; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.imageio.ImageIO; import com.entity.CodeImage; import com.swetake.util.Qrcode; import jp.sourceforge.qrcode.QRCodeDecoder; import jp.sourceforge.qrcode.exception.DecodingFailedException; /** * @author Mongo */ public class QrCode { /** * 生成二维码(QRCode)图片 * * @param flag (是否带中间logo) */ public static void createQRCode(Boolean flag) { try { //================基本信息============================================== /* 要合成的两张图片 */ String logoPath = "D:/logo.png" ; //中间logo图片 String qrcodePath = "D:/qrcode.png" ; //二维码图片 /* 二维码种要存储的信息!(没有的话,二维码不展示!) */ String content = "您的设备已经中毒了,请注意!请注意!" ; /* 合成的二维码的一些特性 */ String format = "png" ; //图片的格式 char correct = 'H' ; // 容错率 char mode = 'B' ; // 类型 int version = 10 ; // 版本(亦能决定合成后的二维码大小) /* 合成后的二维码的宽与高 */ int width = 178 ; int height = 178 ; //===================================================================== Qrcode qrcodeHandler = new Qrcode(); /* 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小 */ qrcodeHandler.setQrcodeErrorCorrect(correct); // 特别注意:这里使用单引号!! 属于 char 类型,不是 String 类型 /* N代表数字,A代表字符a-Z,B代表其他字符 */ qrcodeHandler.setQrcodeEncodeMode(mode); /* 设置设置二维码版本,取值范围1-40,值越大尺寸越大,可存储的信息越大 */ qrcodeHandler.setQrcodeVersion(version); /* 内容 byte 化 */ byte [] contentBytes = content.getBytes( "UTF-8" ); BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D gs = bufImg.createGraphics(); gs.setBackground(Color.WHITE); gs.clearRect( 0 , 0 , width, height); //没有这个,二维码全黑 /* 设置图像颜色 */ gs.setColor(Color.BLACK); /* 设置偏移量 不设置可能导致解析出错 */ int pixoff = 2 ; //中间logo偏移大小 /* 输出内容 > 二维码 */ if (contentBytes.length > 0 && contentBytes.length < width) { boolean [][] codeOut = qrcodeHandler.calQrcode(contentBytes); for ( int i = 0 ; i < codeOut.length; i++) { for ( int j = 0 ; j < codeOut.length; j++) { if (codeOut[j][i]) { gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3 , 3 ); } } } } else { System.err.println( "QRCode content bytes length = " + contentBytes.length + " not in [ 0,200]. " ); } /* 判断是否需要添加logo图片 */ if (flag) { int width_4 = width / 4 ; int width_8 = width_4 / 2 ; int height_4 = height / 4 ; int height_8 = height_4 / 2 ; Image img = ImageIO.read( new File(logoPath)); gs.drawImage(img, width_4 + width_8, height_4 + height_8, width_4, height_4, null ); gs.dispose(); bufImg.flush(); } /* 生成二维码QRCode图片 */ SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMddHHmmss" ); String fileName = sdf.format( new Date()) + "." + format; String url = qrcodePath + fileName; File imgFile = new File(url); if (!imgFile.exists()) { imgFile.mkdirs(); } ImageIO.write(bufImg, format, imgFile); System.out.println( "生成二维码图片成功!" ); } catch (Exception e) { e.printStackTrace(); } } /** * 解析二维码(直接读取二维码信息) */ public static String decode(String imagePath) { // QRCode 二维码图片的文件 File imageFile = new File(imagePath); BufferedImage bufImg = null ; String content = null ; try { bufImg = ImageIO.read(imageFile); QRCodeDecoder decoder = new QRCodeDecoder(); content = new String(decoder.decode( new CodeImage(bufImg)), "utf-8" ); } catch (IOException e) { System.out.println( "Error: " + e.getMessage()); e.printStackTrace(); } catch (DecodingFailedException dfe) { System.out.println( "Error: " + dfe.getMessage()); dfe.printStackTrace(); } return content; } public static void main(String[] args) { Boolean flag = true ; //是否添加中间logo! QrCode.createQRCode(flag); // String content = QrCode.decode("D:/xxxx.png");//解析二维码图片 // System.out.println("结束="+content); } } |
解析二维码则需要一个实体类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package com.entity; import java.awt.image.BufferedImage; import jp.sourceforge.qrcode.data.QRCodeImage; /** * @author Mongo */ public class CodeImage implements QRCodeImage { private BufferedImage bufferedImage; public CodeImage(BufferedImage image){ this .bufferedImage = image; } @Override public int getHeight() { return bufferedImage.getHeight(); } @Override public int getPixel( int x, int y) { return bufferedImage.getRGB(x, y); } @Override public int getWidth() { return bufferedImage.getHeight(); } } |
需要的 jar 包:
Qrcode-C.jar
qrcode-R.jar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通