1. maven
<dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.0</version></dependency><!-- 如果是 web 应用添加--><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.3.0</version></dependency>
2. API
1. 基础API(部分)
类 | 描述 | 方法 | 描述 |
---|---|---|---|
MultiFormatWriter | 用于条码生成,不同类型的条码有各自的Writer类 | encode(String contents, BarcodeFormat var2, int w, int h, Map<EncodeHintType, ?> setting) | 获取BitMatrix对象 setting参数可不传 |
BitMatrix | 条码位矩阵对象 | get(int x, int y) |
获取(x, y)的位值,true表示黑色 |
set(int x, int y) | 设置(x, y)的位值为true(黑) | ||
unset(int x, int y) | 设置(x, y)的位值为false(白) | ||
flip(int x,int y) |
对(x, y)的位值做非运算 | ||
clear() | 清空矩阵 | ||
MatrixToImageWriter | 条码写出对象 | writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config) | 报错条码到本地 matrix:条码位矩阵对象 config参数可无 format: 图片格式 file: 文件路径对象 stream:输出流 file: 文件对象 config:颜色配置,可无 |
writeToStream(BitMatrix matrix, String format, OutputStream stream, MatrixToImageConfig config) | |||
writeToFile(BitMatrix matrix, String format, File file, MatrixToImageConfig config) | |||
toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) | 转换为BufferedImage config参数可无 |
||
MatrixToImageConfig | 颜色配置 | MatrixToImageConfig(int onColor, int offColor) | 构造方法设置条码及背景颜色,无参为白底黑色条码 |
MultiFormatReader | 用于条码解析,不同类型的条码有各自的tReader类 | decode(BinaryBitmap image, Map<DecodeHintType, ?> hints) | 构造方法 |
Binarizer | HybridBinarizer(LuminanceSource source) | 构造方法 | |
LuminanceSource | BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) | 构造方法,参数可只有image | |
Result | 解析结果对象 | getText() | 获取条形码文本内容 |
getBarcodeFormat() | 获取条码类型 | ||
getRawBytes() | 获取原始字节 | ||
getResultPoints() | 获取结果点 |
2.2 常量
类 | 描述 | 常量 | 描述 | 图例与示例 |
---|---|---|---|---|
BarcodeFormat | 条码类型 | AZTEC | 阿兹特克条形码 | |
CODABAR | 自检条码,用于读取印刷形式的条码,特别是使用点阵打印机印刷的条码。它的典型用途包含 Fed-Ex 包裹和血库单 | |||
CODE_39 | 第一个同时使用数字和字母的条码。它是一种可变长度的条码,最多可同时对 43 个字母数字字符进行编码。它最常用于军事和汽车行业。 | |||
CODE_93 | Code 93 条码比 Code 39 条码更新、更安全且更紧凑,能读取字母和数字。它用于军事和汽车领域,还被加拿大邮政用来对特殊投递信息进行编码。 | |||
CODE_128 | 密度最高的一款条码,也是在潜在信息存储方面功能最全的一维条码。它可以解码全部128 ASCII 字符 | |||
DATA_MATRIX | 二维条码 | |||
EAN_8 | 国际物品编码协会制 定的一种商品用条码,EAN-8 条码是 EAN-13 条码的压缩版 EAN_8: 8位数字 EAN_13: 13位数字 |
|||
EAN_13 | ||||
ITF | 交叉二五条码 | |||
MAXICODE | 没有编码器 | |||
PDF_417 | 一种堆叠式二维条码 | |||
QR_CODE | 二维码 | |||
RSS_14 | 没有编码器 | |||
RSS_EXPANDED | 没有编码器 | |||
UPC_A | 由 12 位数字组成 | |||
UPC_E | UPC-E 是标准尺寸的 UPC-A 数字条码的压缩版 | |||
UPC_EAN_EXTENSION | 没有编码器 | |||
EncodeHintType | 编码时的额外参数 | ERROR_CORRECTION | 容错率,指定容错等级,例如二维码中使用的ErrorCorrectionLevel , Aztec使用Integer |
|
CHARACTER_SET | 编码集 | |||
DATA_MATRIX_SHAPE | 指定生成的数据矩阵的形状,类型为SymbolShapeHint |
|||
MIN_SIZE | 最小数量 | |||
MAX_SIZE | 最大数量 | |||
MARGIN | 边距 | |||
PDF417_COMPACT | 指定是否使用PDF417紧凑模式, 类型Boolean |
|||
PDF417_COMPACTION | 指定PDF417的紧凑类型 | |||
PDF417_DIMENSIONS | 指定PDF417的最大最小行列数 | |||
AZTEC_LAYERS | AZTEC编码层数 | |||
QR_VERSION | 指定二维码版本,版本越高越复杂,反而不容易解析 | |||
DecodeHintType | 解码时的额外参数 | OTHER | ||
PURE_BARCODE | Boolean类型,指定图片是一个纯粹的二维码 | |||
POSSIBLE_FORMATS | 可能的编码格式,List类型 | |||
CHARACTER_SET | 编码字符集,通常指定UTF-8 | |||
TRY_HARDER | 花更多的时间用于寻找图上的编码,优化准确性,但不优化速度,Boolean类型 | |||
ALLOWED_LENGTHS | 允许的编码数据长度 - 拒绝多余的数据。不懂这是什么,int[]类型 | |||
ASSUME_CODE_39_CHECK_DIGIT | CODE 39 使用 | |||
ASSUME_GS1 | 使用GS1编码来解析 | |||
RETURN_CODABAR_START_END | CODABAR编码使用 | |||
NEED_RESULT_POINT_CALLBACK | 当解析到可能的结束点时进行回调 ResultPointCallback | |||
ALLOWED_EAN_EXTENSIONS | 允许EAN或UPC编码有额外的长度int[] | |||
ErrorCorrectionLevel | 容错率,指定容错等级 | L | 1 | |
M | 0 | |||
Q | 3 | |||
H | 2 | |||
SymbolShapeHint | 数据矩阵的形状 | FORCE_NONE | 无 | |
FORCE_SQUARE | 正方形 | |||
FORCE_RECTANGLE | 长方形 | |||
MatrixToImageConfig | 条码颜色 | BLACK | 黑色 | |
WHITE | 白色 |
3. 示例
3.1 二维码生成
MultiFormatWriter qrCodeWriter=new MultiFormatWriter();Map<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN,1); //先设置margin为1BitMatrix bitMatrix = qrCodeWriter.encode("https://www.baidu.com", BarcodeFormat.QR_CODE, 500, 500,hints);Path path = FileSystems.getDefault().getPath("D:\\demo\\zxing\\"+System.currentTimeMillis()+"—QR_CODE.png");MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path,new MatrixToImageConfig( -100000,-1777216));
3.2 二维码解码
BufferedImage image = ImageIO.read(new File("D:\\demo\\zxing\\1592875410059—QR_CODE_1.png"));LuminanceSource luminanceSource = new BufferedImageLuminanceSource(image);Binarizer binarizer = new HybridBinarizer(luminanceSource);BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);Map<DecodeHintType, Object> hints = new HashMap<>();hints.put(DecodeHintType.CHARACTER_SET, "utf-8");hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);hints.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);Result result = new QRCodeReader().decode(binaryBitmap, hints);System.out.println(result.getText());
3.3 带loge,背景图片及文字的二维码工具类
package com.example.project.demo;import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;/*** 二维码工具类*/
public class BarcodeUtils {private static final int QRCOLOR = 0xFF000000; // 二维码颜色 默认是黑色private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色private static final int WIDTH = 215; // 二维码宽private static final int HEIGHT = 215; // 二维码高private static final int WORDHEIGHT = 235; // 加文字二维码高/*** 用于设置QR二维码参数*/private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {private static final long serialVersionUID = 1L;{// 设置QR二维码的纠错级别(H为最高级别)具体级别信息put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置编码方式put(EncodeHintType.CHARACTER_SET, "utf-8");put(EncodeHintType.MARGIN, 0);}};/*** 设置 Graphics2D 属性 (抗锯齿)** @param graphics2D*/private static void setGraphics2D(Graphics2D graphics2D) {graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);graphics2D.setStroke(s);}/*** 生成二维码图片存储到filePath中** @param content 二维码内容* @param filePath 成二维码图片保存路径* @return*/public static boolean createImg(String content, String filePath) {boolean flag = false;try {MultiFormatWriter multiFormatWriter = new MultiFormatWriter();BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);// 图片输出路径String code = content.split("=")[1]; // 设备编号File file = new File(filePath + "//PSD" + code + ".jpg");if (!file.exists()) {// 如果文件夹不存在则创建file.mkdirs();}// 输出二维码图片到文件夹MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file);flag = true;} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}return flag;}/*** 把带logo的二维码下面加上文字** @param image* @param words* @return*/private static BufferedImage insertWords(BufferedImage image, String words) {// 新的图片,把带logo的二维码下面加上文字if (StringUtils.isNotEmpty(words)) {//创建一个带透明色的BufferedImage对象BufferedImage outImage = new BufferedImage(WIDTH, WORDHEIGHT, BufferedImage.TYPE_INT_ARGB);Graphics2D outg = outImage.createGraphics();setGraphics2D(outg);// 画二维码到新的面板outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);// 画文字到新的面板Color color = new Color(183, 183, 183);outg.setColor(color);// 字体、字型、字号outg.setFont(new Font("微软雅黑", Font.PLAIN, 18));//文字长度int strWidth = outg.getFontMetrics().stringWidth(words);//总长度减去文字长度的一半 (居中显示)int wordStartX = (WIDTH - strWidth) / 2;//height + (outImage.getHeight() - height) / 2 + 12int wordStartY = HEIGHT + 10;// 画文字outg.drawString(words, wordStartX, wordStartY);outg.dispose();outImage.flush();return outImage;}return null;}/*** @param logoFile loge图片的路径* @param bgFile 背景图片的路径* @param codeFile 图片输出路径* @param qrUrl 二维码内容* @param words 二维码下面的文字* @description 生成带logo的二维码图片 二维码下面带文字*/public static void drawLogoQRCode(File logoFile, File bgFile, File codeFile, String qrUrl, String words) {try {MultiFormatWriter multiFormatWriter = new MultiFormatWriter();// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色for (int x = 0; x < WIDTH; x++) {for (int y = 0; y < HEIGHT; y++) {image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);}}//把logo画到二维码上面if (Objects.nonNull(logoFile) && logoFile.exists()) {// 构建绘图对象Graphics2D g = image.createGraphics();setGraphics2D(g);// 读取Logo图片BufferedImage logo = ImageIO.read(logoFile);// 开始绘制logo图片 等比缩放:(width * 2 / 10 height * 2 / 10)不需缩放直接使用图片宽高//width * 2 / 5 height * 2 / 5 logo绘制在中心点位置g.drawImage(logo, WIDTH * 2 / 5, HEIGHT * 2 / 5, logo.getWidth(), logo.getHeight(), null);g.dispose();logo.flush();}// 新的图片,把带logo的二维码下面加上文字image = insertWords(image, words);image.flush();ImageIO.write(image, "png", codeFile);} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {//logoFile logoFile = new File("D:\\demo\\zxing\\1592875410059—QR_CODE_1.png");//背景图片File bgFile = new File("D:\\demo\\zxing\\1.jpg");//生成图片File qrCodeFile = new File("D:\\demo\\zxing\\12345.png");//二维码内容String url = "https://w.url.cn/s/AYmfAV3";//二维码下面的文字String words = "PSD000001";drawLogoQRCode(logoFile, bgFile, qrCodeFile, url, words);}
}
3.4 可带内容文本的条形码工具类
package com.example.project.demo;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Hashtable;public class Code_128Utils {private static final int WIDTH = 351;private static final int CODEHEIGHT = 55;private static final int HEIGHT = 78;private static final int FONTSIZE = 25;private static final String IMAGETYPE = "JPEG";/**** @param no 条形码内容* @param codePath* @param isShowNum*/public static void createCode(String no, String codePath, Boolean isShowNum) throws Exception {FileOutputStream fos;fos = new FileOutputStream(new File(codePath));int width = WIDTH;int height = CODEHEIGHT;Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");BitMatrix m = new MultiFormatWriter().encode(no,BarcodeFormat.CODE_128, width, height, hints);MatrixToImageWriter.writeToStream(m, IMAGETYPE, fos);fos.flush();fos.close();if(isShowNum){createFont(no, codePath);}}///该方法用来生成二维码字体并且把二维码拼接到字体图片上private static void createFont(String no, String codePath) throws Exception {BufferedImage font = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);BufferedImage code = ImageIO.read(new File(codePath));Graphics2D g = (Graphics2D) font.getGraphics();//长宽是总的 字体加二维码的g.clearRect(0, 0, WIDTH, HEIGHT);g.setColor(Color.WHITE);g.fillRect(0, 0, WIDTH, HEIGHT);//字体渲染g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);//在图片上把字写好for (int i = 0; i < no.length(); i++) {g.setColor(Color.black);Font font_ = new Font("Consolas", 0, FONTSIZE);g.setFont(font_);g.drawString(no.charAt(i) + "", (FONTSIZE * 2 + WIDTH - no.length()* FONTSIZE)/ 2 + (i - 1) * FONTSIZE, CODEHEIGHT + HEIGHT - CODEHEIGHT);}//然后把二维码加上去 g.drawImage(code, 0, 0, null);g.dispose();//进行图片处理,防止出现模糊int[] rgb = new int[3];for (int i = 0; i < WIDTH; i++) {for (int j = CODEHEIGHT; j < HEIGHT; j++) {int pixel = font.getRGB(i, j);rgb[0] = (pixel & 0xff0000) >> 16;rgb[1] = (pixel & 0xff00) >> 8;rgb[2] = (pixel & 0xff);if (rgb[0] > 125 || rgb[1] > 125 || rgb[2] > 125) {font.setRGB(i, j, -1);}if (rgb[0] < 100 || rgb[1] < 100 || rgb[2] < 100) {font.setRGB(i, j, -16777216);}}}File outputfile = new File(codePath);ImageIO.write(font, IMAGETYPE, outputfile);}public static void main(String[] args) throws Exception {String s = "D:\\demo\\zxing\\"+System.currentTimeMillis()+".jpg";createCode("S1234567", s,false);}
}