二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点。本文介绍通过 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. C#使用DotNetZip对zip压缩包进行添加删除操作

    参考:http://stackoverflow.com/questions/9855155/how-can-i-delete-a-directory-in-a-zip-file-using-net D ...

  2. springboot之热部署

    一.介绍: spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. 二 ...

  3. 二十四、详述 IntelliJ IDEA 中自动生成 serialVersionUID 的方法

    当我们用 IntelliJ IDEA 编写类并实现 Serializable(序列化)接口的时候,可能会遇到这样一个问题,那就是: 无法自动生成serialVersionUID. 而serialVer ...

  4. MVCPager分页使用方法

    public ActionResult AdminUserList(UserListModel model) { var pagedList = _userService.SearchAdminUse ...

  5. WINDOWS 负载均衡NLB配置中单播与多播区别(转载)

    单播 在单播模式下,NLB重新对每个NLB节点中启用NLB的网络适配器分配MAC地址(此MAC地址称为群集MAC地址),并且所有的NLB节点均使用相同的MAC地址(均使用群集MAC地址),同时NLB修 ...

  6. 【前端框架-Vue-基础】$attr及$listeners实现跨多级组件的通信

    父子 A 组件与 B 组件之间的通信: (父子组件) 如上图所示,A.B.C三个组件依次嵌套,按照 Vue 的开发习惯,父子组件通信可以通过以下方式实现: A to B 通过props的方式向子组件传 ...

  7. 09 OCP知识点讲解 之 LRU链与脏LRU链

    OCP知识点讲解 之 LRU链与脏LRU链 分类: Oracle 2012-06-30 10:49:26   一.LRU链: 任何缓存的大小都是有限制的,并且总不如被缓存的数据多.就像Buffer c ...

  8. Elasticsearch 聚合操作

    数据准备: PUT /shop { "settings": { "number_of_shards": 3, "number_of_replicas& ...

  9. Mysql是否开启binlog日志&开启方法

    运行sql   show variables like 'log_bin'; 如果Value 为 OFF 则为开启日志文件 如何开启mysql日志? 找到my,cnf 中 [mysqld]  添加如下 ...

  10. BGP扩展属性

    安全特性: BGP安全特性: MD5 GTSM:通用TTL安全保护机制通过对TTL的检测来达到防止攻击的目的,如果攻击者模拟真实的BGP协议报文(TCP),对一台路由器不断地发送报文,路由器接收报文后 ...