Java基于zxing生成二维码矩阵过程解析
作者:海绵般汲取 发布时间:2023-11-23 06:04:06
标签:java,zxing,二维码
这个例子需要使用google的开源项目zxing的核心jar包
core-3.2.0.jar
可以百度搜索下载jar文件,也可使用maven添加依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.0</version>
</dependency>
下面是将生成的二维码矩阵写入到jpg文件中。
* 生成二维码图片
* @param dir 存放的目录
* @param fileName 文件名要以.jpg结尾
* @param content 这个内容可以是文字或链接
*/
public static void generateQRCode(String dir, String fileName, String content) {
//生成二维码的宽高
int size = 400;
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
// 指定编码格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 指定二维码的边距,设置后无效,,设置纠错等级ErrorCorrectionLevel.H为高等级时,无效 //hints.put(EncodeHintType.MARGIN, 1);
try {
//encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints)
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
//bitMatrix = updateBit(bitMatrix, 20);
File file1 = new File(dir);
if (!file1.exists()) {
file1.mkdirs();
}
//将生成的矩阵像素写入到指定文件中,这里是以jpg结尾
MatrixToImageWriter.writeToStream(bitMatrix, "jpg", new FileOutputStream(dir + "/" + fileName));
System.out.println("创建成功");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
上面指定了纠错等级设置有四个值
/** L = ~7% correction */
L(0x01),
/** M = ~15% correction */
M(0x00),
/** Q = ~25% correction */
Q(0x03),
/** H = ~30% correction */
H(0x02);
指定为L,M这两个等级时,二维码大小会根据其存储的数据量变化,即边距肯能会很大,看下图,
Q,H高等级时,会按照标准格式显示二维码图片。建议使用H等级。
这里生成的二维码留的白色边距有点多,想要适当减小边距,看下图
如果不想边距太大,我们可以将生成的二维码图片进行剪切。新建立一个空的BitMatrix对象来放这个二维码
margin为白色边距的大小
private static BitMatrix updateBit(BitMatrix matrix, int margin) {
int tempM = margin * 2;
//left,top,width,height
// 0 1 2 3 对应的数组下标
//这里的width和height是指去除白色边框后的真实的二维码长宽,而不是图片长宽。
int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性
int resWidth = rec[2] + tempM;//真实宽度加左右边距
int resHeight = rec[3] + tempM;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix
resMatrix.clear();
//从上->下按列进行值得复制,即一列一列的扫描到新的二维矩阵中
for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中
for (int j = margin; j < resHeight - margin; j++) {
//margin + rec[0]
if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
resMatrix.set(i, j);
}
}
}
return resMatrix;
}
生成二维码
这样白色边距就不会太大了,好看多了
后面还有将二维码嵌入到海报,或者其他活动图片上的方法,直接上代码
将二维码放置在图片右下角的位置
public void insertQRCode(BufferedImage zxingImage, String backgroundPath) {
InputStream dest = null;
try {
dest = new FileInputStream(backgroundPath);
BufferedImage image = ImageIO.read(dest);
Graphics g = image.getGraphics();
int leftMargin = image.getWidth() - zxingImage.getWidth() - 10;
int topMargin = image.getHeight() - zxingImage.getHeight() - 10;
g.drawImage(zxingImage, leftMargin, topMargin, zxingImage.getWidth(), zxingImage.getHeight(), null);
ImageIO.write(image, "jpg", new FileOutputStream("D:\\QRCode\\zengmei.jpg"));
System.out.println("创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
生成后的结果,图片是本地随便找了一张图片
修改二维码线条颜色,在二维码中插入logo图标等方法
发现修改二维码颜色之后,用微信,qq扫描二维码很难被识别。这个很难受。这里说下怎么改。
修改原理就是,将内容通过new MultiFormatWriter().encode()方法生成二维矩阵后,,
用一个新的BufferedImage对象作为容器给矩阵的两个不同的值设置颜色,有值得为true,没值false,即设置黑白两种颜色
/**
*
* @param onColor 二维码的颜色,即黑白二维码的黑色 :0xFF000000 蓝色 0xFF000055
* @param offColor 二维码的背景色 如白色:0xFFFFFFFF
*/
public static void generateOtherQRCode(int onColor, int offColor) {
String content = "小姐姐最棒啦^_^";
int size = 200;
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
// 指定编码格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix,
new MatrixToImageConfig(onColor, offColor));
ImageIO.write(image, "png", new FileOutputStream("D:/QRCode/beautiful.png"));
System.out.println("操作成功");
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
}
重要方法是:MatrixToImageWriter.toBufferedImage
也就是设置颜色,然后返回BufferImage对象
public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
int onColor = config.getPixelOnColor();
int offColor = config.getPixelOffColor();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
}
}
return image;
}
//imageType , zxing支持的图像类型有三种,黑白颜色的默认为BufferedImage.TYPE_BYTE_BINARY = 12,图像不带透明度alpha 最多是4bit的的图像TYPE_INT_RGB 这个是不带alpha的8bit图像TYPE_INT_ARGB 这个带alpha的8bit图像
java.awt.image.BufferedImage.BufferedImage(int width, int height, int imageType)
开源项目地址
https://github.com/zxing/zxing
来源:https://www.cnblogs.com/gne-hwz/p/9445466.html


猜你喜欢
- 一、概述数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等,可动态地改变透视表版面布置,也可以重新安排行
- 本文实例为大家分享了Flutter自定义圆盘取色器的具体代码,供大家参考,具体内容如下下面展示一些 内联代码片。圆盘取色器效果图完整代码im
- 今天突然想起来,java产生随机数的问题,上机试了一下,找到了一点区别,在这里总结一下;直接调用Math.random()是产生一个[0,1
- 概述Spring Cloud中,客户端的负载均衡使用的是Ribbon,Ribbon的超时时间默认很短,需要进行调整。Spring Cloud
- spring-MVC实现简单的登录功能,供大家参考,具体内容如下今天我学习了spring-MVC实现简单的登录功能,本篇博客就讲解如何使用s
- 这篇文章主要介绍了JAVA泛型的继承和实现、擦除原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 1,刚刚在别人开源的项目中看到了一个挺不错的用户体验,效果图如下:2,那下面我们就来实现一下,首先看一下布局,由于一般只是我们包含头像的那部
- 最近看Android FrameWork层代码,看到了ThreadLocal这个类,有点儿陌生,就翻了各种相关博客一一拜读;自己随后又研究了
- 1.下载jdk8 1)官网下载地址Java8下载官网地址:http://www.oracle.com/technetwork/java/ja
- 一,SQL注入–1,需求–1,利用jdbc查询user的信息,如果信息正确就登录,否则提示错误–1,创建user表,指定字段id name
- 本文实例为大家分享了Java实现打字游戏的具体代码,供大家参考,具体内容如下新建一个项目,然后在src里面建一个MyGame.java文件,
- 什么是队列结构一种线性结构,具有特殊的运算法则【只能在一端(队头)删除,在另一端(队尾)插入】。分类:顺序队列结构链式队列结构基本操作:入队
- 写在前面最近在研究Spring Cloud和Spring Cloud Alibaba源码,在看到Nacos的配置中心的时候,有注意到自动刷新
- 上一节我们完成了使用DataGrid显示所有商品信息,这节我们开始添加几个功能:添加、更新、删除和查询。首先我们实现下前台的显示,然后再做后
- C#调用MFC 窗口 DLLMFC DLL创建一个窗口类,加public和AFX_EXT_CLASSMFC DLL属性注意MFC的使用:在共
- Java5以后开始支持枚举类型,枚举类型使用起来非常方便,其重要的作用是作为类型安全使用的。如果在不考虑系统内存开销的情况下大量的使用枚举也
- 1.下载idea的 《.ignore》 插件,重启idea生效2.添加自己想要忽略的文件夹及文件,一般选这个就够了3.如果想要忽略提交的文件
- 在定位JVM性能问题时可能会遇到内存泄露导致JVM OutOfMemory的情况,在使用Tomcat容器时如果设置了reloadable=”
- BroadcastReceiver(广播 * ),在Android开发中,BroadcastReceiver的应用场景非常多,属于Andro
- Maven导入thymeleaf依赖飘红1、运行环境操作系统:win10jdk版本:1.8idea版本:2020.1maven版本:3.3.