spring boot:用zxing生成二维码,支持logo(spring boot 2.3.2)
一,zxing是什么?
1,zxing的用途
如果我们做二维码的生成和扫描,通常会用到zxing这个库,
ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库。
zxing还可以实现使用手机的内置的摄像头完成条形码的扫描及解码
2,zxing官方项目地址:
https://github.com/zxing/zxing
说明:刘宏缔的架构森林是一个专注架构的博客,
网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/05/24/springboot-yong-zxing-sheng-cheng-er-wei-ma-zhi-chi-logospringboot232/
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的相关信息
1,项目地址
https://github.com/liuhongdi/qrcode
2, 项目功能说明:
生成二维码直接展示
生成二维码保存成图片
解析二维码图片中的文字信息
3,项目结构,如图:
三,配置文件说明
1,pom.xml
<!--qrcode begin--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.4.0</version> </dependency> <!--qrcode end-->
导入zxing库供生成qrcode使用
四,java代码说明
1,QrCodeUtil.java
/** * 二维码工具类 * by liuhongdi */ public class QrCodeUtil { //编码格式,采用utf-8 private static final String UNICODE = "utf-8"; //图片格式 private static final String FORMAT = "JPG"; //二维码宽度像素pixels数量 private static final int QRCODE_WIDTH = 300; //二维码高度像素pixels数量 private static final int QRCODE_HEIGHT = 300; //LOGO宽度像素pixels数量 private static final int LOGO_WIDTH = 100; //LOGO高度像素pixels数量 private static final int LOGO_HEIGHT = 100; //生成二维码图片 //content 二维码内容 //logoPath logo图片地址 private static BufferedImage createImage(String content, String logoPath) throws Exception { Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.put(EncodeHintType.CHARACTER_SET, UNICODE); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT, 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 (logoPath == null || "".equals(logoPath)) { return image; } // 插入图片 QrCodeUtil.insertImage(image, logoPath); return image; } //在图片上插入LOGO //source 二维码图片内容 //logoPath LOGO图片地址 private static void insertImage(BufferedImage source, String logoPath) throws Exception { File file = new File(logoPath); if (!file.exists()) { throw new Exception("logo file not found."); } Image src = ImageIO.read(new File(logoPath)); int width = src.getWidth(null); int height = src.getHeight(null); if (width > LOGO_WIDTH) { width = LOGO_WIDTH; } if (height > LOGO_HEIGHT) { height = LOGO_HEIGHT; } Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); src = image; // 插入LOGO Graphics2D graph = source.createGraphics(); int x = (QRCODE_WIDTH - width) / 2; int y = (QRCODE_HEIGHT - height) / 2; graph.drawImage(src, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); graph.setStroke(new BasicStroke(3f)); graph.draw(shape); graph.dispose(); } //生成带logo的二维码图片,保存到指定的路径 // content 二维码内容 // logoPath logo图片地址 // destPath 生成图片的存储路径 public static String save(String content, String logoPath, String destPath) throws Exception { BufferedImage image = QrCodeUtil.createImage(content, logoPath); File file = new File(destPath); String path = file.getAbsolutePath(); File filePath = new File(path); if (!filePath.exists() && !filePath.isDirectory()) { filePath.mkdirs(); } String fileName = file.getName(); fileName = fileName.substring(0, fileName.indexOf(".")>0?fileName.indexOf("."):fileName.length()) + "." + FORMAT.toLowerCase(); System.out.println("destPath:"+destPath); ImageIO.write(image, FORMAT, new File(destPath)); return fileName; } //生成二维码图片,直接输出到OutputStream public static void encode(String content, String logoPath, OutputStream output) throws Exception { BufferedImage image = QrCodeUtil.createImage(content, logoPath); ImageIO.write(image, FORMAT, output); } //解析二维码图片,得到包含的内容 public static String decode(String path) throws Exception { File file = new File(path); BufferedImage image = ImageIO.read(file); if (image == null) { return null; } BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(); hints.put(DecodeHintType.CHARACTER_SET, UNICODE); result = new MultiFormatReader().decode(bitmap, hints); return result.getText(); } }
工具类,包含了生成二维码、保存二维码,展示二维码,解析二维码
2,HomeController.java
@RequestMapping("/home") @Controller public class HomeController { //生成带logo的二维码到response @RequestMapping("/qrcode") public void qrcode(HttpServletRequest request, HttpServletResponse response) { String requestUrl = "http://www.baidu.com"; try { OutputStream os = response.getOutputStream(); QrCodeUtil.encode(requestUrl, "/data/springboot2/logo.jpg", os); } catch (Exception e) { e.printStackTrace(); } } //生成不带logo的二维码到response @RequestMapping("/qrnologo") public void qrnologo(HttpServletRequest request, HttpServletResponse response) { String requestUrl = "http://www.baidu.com"; try { OutputStream os = response.getOutputStream(); QrCodeUtil.encode(requestUrl, null, os); } catch (Exception e) { e.printStackTrace(); } } //把二维码保存成文件 @RequestMapping("/qrsave") @ResponseBody public String qrsave() { String requestUrl = "http://www.baidu.com"; try { QrCodeUtil.save(requestUrl, "/data/springboot2/logo.jpg", "/data/springboot2/qrcode2.jpg"); } catch (Exception e) { e.printStackTrace(); } return "文件已保存"; } //解析二维码中的文字 @RequestMapping("/qrtext") @ResponseBody public String qrtext() { String url = ""; try { url = QrCodeUtil.decode("/data/springboot2/qrcode2.jpg"); } catch (Exception e) { e.printStackTrace(); } return "解析到的url:"+url; } }
入口处包含了四个方法,接下来我们做测试
五,测试效果
1,生成不带logo的二维码,访问:
http://127.0.0.1:8080/home/qrnologo
效果:
2,生成带logo的二维码:访问
http://127.0.0.1:8080/home/qrcode
效果:
3,生成二维码保存成文件:访问:
http://127.0.0.1:8080/home/qrsave
代码中文件被保存成了:/data/springboot2/qrcode2.jpg
4,解析二维码中包含的文字信息:访问:
http://127.0.0.1:8080/home/qrtext
返回:
解析到的url:http://www.baidu.com
成功解析到了图片中包含的url地址
六,查看spring boot版本
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.2.RELEASE)