二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点。本文介绍通过 google 的 zxing 包生成带 logo 的二维码的过程,供大家参考。

ZXing的github地址:https://github.com/zxing/zxing

一、引入zxing所需依赖

<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>

二、二维码工具类实现

package com.psk.hms.base.util;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable; /**
* 二维码生成及读取工具类
*
* @author chenj.
* @version 1.0
* @since 2019/3/14 18:46
*/
public class QRCodeUtil {
private static final String CHARSET = "UTF-8";
private static final String FORMAT_NAME = "JPG";
// 二维码尺寸
private static final int QRCODE_SIZE = 200;
// LOGO宽度
private static final int WIDTH = 60;
// LOGO高度
private static final int HEIGHT = 60; /**
* 创建二维码图片
*
* @param content 二维码内容
* @param logoImgPath Logo
* @param needCompress 是否压缩Logo
* @return 返回二维码图片
* @throws WriterException
* @throws IOException BufferedImage
*/
private static BufferedImage createImage(String content, String logoImgPath, boolean needCompress) throws WriterException, IOException {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, 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 (logoImgPath == null || "".equals(logoImgPath)) {
return image;
} // 插入图片
QRCodeUtil.insertImage(image, logoImgPath, needCompress);
return image;
} /**
* 添加Logo
*
* @param source 二维码图片
* @param logoImgPath Logo
* @param needCompress 是否压缩Logo
* @throws IOException void
*/
private static void insertImage(BufferedImage source, String logoImgPath, boolean needCompress) throws IOException {
File file = new File(logoImgPath);
if (!file.exists()) {
return;
} Image src = ImageIO.read(new File(logoImgPath));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > WIDTH) {
width = WIDTH;
} if (height > HEIGHT) {
height = 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_SIZE - width) / 2;
int y = (QRCODE_SIZE - 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的二维码
*
* @param content 二维码内容
* @param logoImgPath Logo
* @param destPath 二维码输出路径
* @param needCompress 是否压缩Logo
* @throws Exception void
*/
public static void encode(String content, String logoImgPath, String destPath, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress);
mkdirs(destPath);
ImageIO.write(image, FORMAT_NAME, new File(destPath));
} /**
* 生成不带Logo的二维码
*
* @param content 二维码内容
* @param destPath 二维码输出路径
*/
public static void encode(String content, String destPath) throws Exception {
QRCodeUtil.encode(content, null, destPath, false);
} /**
* 生成带Logo的二维码,并输出到指定的输出流
*
* @param content 二维码内容
* @param logoImgPath Logo
* @param output 输出流
* @param needCompress 是否压缩Logo
*/
public static void encode(String content, String logoImgPath, OutputStream output, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress);
ImageIO.write(image, FORMAT_NAME, output);
} /**
* 生成不带Logo的二维码,并输出到指定的输出流
*
* @param content 二维码内容
* @param output 输出流
* @throws Exception void
*/
public static void encode(String content, OutputStream output) throws Exception {
QRCodeUtil.encode(content, null, output, false);
} /**
* 二维码解析
*
* @param file 二维码
* @return 返回解析得到的二维码内容
* @throws Exception String
*/
public static String decode(File file) throws Exception {
BufferedImage image;
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, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
} /**
* 二维码解析
*
* @param path 二维码存储位置
* @return 返回解析得到的二维码内容
* @throws Exception String
*/
public static String decode(String path) throws Exception {
return QRCodeUtil.decode(new File(path));
} /**
* 判断路径是否存在,如果不存在则创建
*
* @param dir 目录
*/
public static void mkdirs(String dir) {
if (dir != null && !"".equals(dir)) {
File file = new File(dir);
if (!file.isDirectory()) {
file.mkdirs();
}
}
}
}

三、测试

1、生成不带Logo的二维码

public static void main(String[] args) throws Exception {
String dir = "d:/qrcode.jpg";
String content = "https://www.cnblogs.com/jimc";
File file = new File(dir);
QRCodeUtil.encode(content, new FileOutputStream(file));
System.out.println(QRCodeUtil.decode(file));
}

生成效果:

2、生成带Logo的二维码

public static void main(String[] args) throws Exception {
String dir = "d:/qrcode.jpg";
String content = "https://www.cnblogs.com/jimc/";
String logoImgPath = "d:/logo.png";
File file = new File(dir);
QRCodeUtil.encode(content, logoImgPath, new FileOutputStream(file), true);
System.out.println(QRCodeUtil.decode(file));
}

生成效果:

通过 zxing 生成二维码的更多相关文章

  1. (转)ZXing生成二维码和带logo的二维码,模仿微信生成二维码效果

    场景:移动支付需要对二维码的生成与部署有所了解,掌握目前主流的二维码生成技术. 1 ZXing 生成二维码 首先说下,QRCode是日本人开发的,ZXing是google开发,barcode4j也是老 ...

  2. zxing生成二维码设置边框颜色

    真是研究了很久很久,满满的泪啊 zxing生成二维码,默认是可以增加空白边框的,但是并没有可以设置边框颜色的属性. 其中增加空白边框的属性的一句话是: Map hints = new HashMap( ...

  3. java学习-zxing生成二维码矩阵的简单例子

    这个例子需要使用google的开源项目zxing的核心jar包 core-3.2.0.jar 可以百度搜索下载jar文件,也可使用maven添加依赖 <dependency> <gr ...

  4. 通过zxing生成二维码

    二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点.本文介绍通过 google 的 zxing 包生成带 logo 的二维 ...

  5. 使用google zxing生成二维码图片

    生成二维码工具类: 1 import java.awt.geom.AffineTransform; 2 import java.awt.image.AffineTransformOp; 3 impor ...

  6. Java使用ZXing生成二维码条形码

    一.下载Zxingjar包 本实例使用的是 zxing3.2.0的版本  下载地址 http://pan.baidu.com/s/1gdH7PzP 说明:本实例使用的3.2.0版本已经使用的java7 ...

  7. C# WPF使用ZXing生成二维码ImageSource

    介绍: 如果需要实在WPF窗体程序中现类似如下的二维码图片生成功能,可以通过本文的方法实现 添加步骤: 1.在http://zxingnet.codeplex.com/站点上下载ZXing .Net的 ...

  8. 提高zxing生成二维码的容错率及zxing生成二维码的边框设置

    最近做了一个项目要生成二维码,跟几年前不同,最近大家都喜欢在二维码中间加logo. 加logo倒是不难,两个图片叠一起就是了,但是遇到一个新问题,logo加得太大的话,会导致二维码扫描不出来;加的太小 ...

  9. 使用zxing生成二维码 - servlet形式

    因为项目有个功能需要打印二维码,因为我比较喜欢使用html+css+js实现,所以首先想到的是jquery.qrcode.js插件,这个插件可以用canvas和table生成二维码,效果也不错,不过对 ...

  10. zxing生成二维码和条码

    /*** * 生成二维码方法 * @param str 生成内容 * @param widthHeight 宽度和高度 * @return * @throws WriterException */ p ...

随机推荐

  1. 【CSS单位】px、em、rem

    1.PX为单位 在Web页面初期制作中,我们都是使用“px”来设置我们的文本,因为他比较稳定和精确.但是这种方法存在一个问题,当用户在浏览器中浏览我们制作的Web页面时,他改变了浏览器的字体大小,这时 ...

  2. linq 和lamba表达式

    一.什么是Linq(what)二.Linq的优点(why)三.Linq查询的步骤(how)四.查询基本操作五.結合實例代碼(具體聯繫用linqtosql來寫的增刪改查)一.什么是Linq(what). ...

  3. 使用@AspectJ注解开发Spring AOP

    一.实体类: Role public class Role { private int id; private String roleName; private String note; @Overr ...

  4. nodejs中如何连接mysql

    nodejs中如何连接mysql,下面给出一个小Demo. 第一步安装mysql模块npm install mysql 第二步导入mysql模块var mysql = require('mysql') ...

  5. UIScrollView的常用属性

    UIScrollView的常用属性

  6. ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现

    ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现 承接 http://www.wowotech.net/pm_subsystem/suspend_and_re ...

  7. 05JavaScript语句

    1.JavaScript 语句 JavaScript 语句是发给浏览器的命令. 这些命令的作用是告诉浏览器要做的事情. 2.分号 ; 分号用于分隔 JavaScript 语句. 通常我们在每条可执行的 ...

  8. vue 新属性学习

    1, $listeners 父级元素 <base-input v-on:focus.native="onFocus"></base-input> 子级元素 ...

  9. node 版本升级,版本管理,版本切换

    查看node版本 node -v 升级步骤 1,清除node缓存 sudo npm cache clean -f 2,安装n模块 sudo npm install -g n 3,升级到稳定版本 sud ...

  10. Python3爬虫(十六) pyspider框架

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.pyspider介绍1.基本功能 提供WebUI可视化功能,方便编写和调试爬虫 提供爬取进度监控.爬取结果查看 ...