Java zxing实现生成并解析二维码与条形码
作者:蓝眸少年CY
这篇文章主要为大家详细介绍了Java如何通过zxing实现生成并解析二维码与条形码,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
1、maven依赖
<!--zxing依赖--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.1.0</version> </dependency>
2、一些重要属性方法
BarcodeFormat (码类型)
设置生成条形码的类型。
如:二维码、EAN-13码、UPC-A码、Code-128码、Code-39码等等。
条形码类型 |
BarcodeFormat.AZTEC 阿兹特克码 |
BarcodeFormat.CODABAR Codabar码 |
BarcodeFormat.CODE_39 CODE-30码 |
BarcodeFormat.CODE_93 CODE-93码 |
BarcodeFormat.CODE_128 CODE-128码 |
BarcodeFormat.DATA_MATRIX 矩阵式二维条码 |
BarcodeFormat.EAN_8 EAN-8码 |
BarcodeFormat.EAN_13 EAN-13码 |
BarcodeFormat.ITF 交插二五条码 |
BarcodeFormat.MAXICODE MaxiCode二维条码 |
BarcodeFormat.PDF_417 ; PDF417 |
BarcodeFormat.QR_CODE 二维码 |
BarcodeFormat.RSS_14 RSS 14 |
BarcodeFormat.RSS_EXPANDED RSS EXPANDED |
BarcodeFormat.UPC_A UPC A |
BarcodeFormat.UPC_E UPC E |
BarcodeFormat.UPC_EAN_EXTENSION UPC EAN EXTENSION |
EncodeHintType(自定义属性)
3、带logo得到二维码生成
/** * @description: 二维码生成 * @author: HK * @since: 2024/11/4 10:16 */ public class Test3 { private static final Integer CODE_WIDTH = 300; // 基础属性:二维码宽度,单位像素 private static final Integer CODE_HEIGHT = 300; // 基础属性:二维码高度,单位像素 private static final Integer FRONT_COLOR = 0x000000; // 基础属性:二维码前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基础属性:二维码背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { //设置生成二维码的内容 String qrMessage = "https://www.baidu.com"; // EncodeHintType:编码提示类型,枚举类型 // EncodeHintType.CHARACTER_SET:设置字符编码类型 // EncodeHintType.ERROR_CORRECTION:设置误差校正 // ErrorCorrectionLevel:误差校正等级, // L = ~7% correction、M = ~15% correction、 // Q = ~25% correction、H = ~30% correction // 不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的 // EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近 Map<EncodeHintType, Object> typeObjectHashMap = new HashMap<EncodeHintType, Object>(); typeObjectHashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); typeObjectHashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); typeObjectHashMap.put(EncodeHintType.MARGIN, 1); // MultiFormatWriter:多格式写入,这是一个工厂类,里面重载了两个 encode 方法,用于写入条形码或二维码 // encode(String contents,BarcodeFormat format,int width, int height,Map<EncodeHintType,?> hints) // 参数1:contents:条形码/二维码内容 // 参数2:format:编码类型,如 条形码,二维码 等 // 参数3:width:码的宽度 // 参数4:height:码的高度 // 参数5:hints:码内容的编码类型 // BarcodeFormat:枚举该程序包已知的条形码格式,即创建何种码,如 1 维的条形码,2 维的二维码 等 // BitMatrix:位(比特)矩阵或叫2D矩阵,也就是需要的二维码 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter .encode(qrMessage, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, typeObjectHashMap); // java.awt.image.BufferedImage:具有图像数据的可访问缓冲图像,实现了 RenderedImage 接口 // BitMatrix 的 get(int x, int y) 获取比特矩阵内容,指定位置有值,则返回true,将其设置为前景色,否则设置为背景色 // BufferedImage 的 setRGB(int x, int y, int rgb) 方法设置图像像素 // 参数1 x:像素位置的横坐标,即列 // 参数2 y:像素位置的纵坐标,即行 // 参数3 rgb:像素的值,采用 16 进制,如 0xFFFFFF 白色 BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR); for (int x = 0; x < CODE_WIDTH; x++) { for (int y = 0; y < CODE_HEIGHT; y++) { bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); } } // 把logo图片设置到二维码中间位置(若不想在二维码中间插入logo图片则不执行此条代码) insertLogoImage(bufferedImage, new FileInputStream("d://hello.jpg")); // javax.imageio.ImageIO java扩展的图像IO // write(RenderedImage im,String formatName,File output) // im:待写入的图像 // formatName:图像写入的格式 // output:写入的图像文件,文件不存在时会自动创建 // 即将保存的二维码图片文件 ImageIO.write(bufferedImage, "png", new FileOutputStream("d://hello.png")); } /*** * 为二维码插入中间的logo图片 * @param bufferedImage 二维码图片信息 * @param logoInput logo图片位置 * @throws IOException 抛出IO异常 */ private static void insertLogoImage(BufferedImage bufferedImage, InputStream logoInput) throws IOException { // 加载Logo图片到Image对象 Image logoImage = ImageIO.read(logoInput); // 设置二维码中间的Logo图片(设置logo图片的宽高需要保持和二维码宽高的一半宽高) int logoWidth = CODE_WIDTH / 5; int logoHeight = CODE_HEIGHT / 5; // 按照指定的宽高进行等比缩放(若设置的宽高比之前大则代表放大),并将缩放后的图片绘制到一个新的BufferedImage对象中 Image image = logoImage.getScaledInstance(logoWidth, logoHeight, Image.SCALE_SMOOTH); BufferedImage logoBufferedImage = new BufferedImage(logoWidth, logoHeight, BufferedImage.TYPE_INT_RGB); // 获取图形上下文对象,用于后续将缩放后的图片绘制在 logoBufferedImage 对象上 Graphics graphics = logoBufferedImage.getGraphics(); // 绘制缩放后的图片到 logoBufferedImage 对象上,使其填满整个画布 graphics.drawImage(image, 0, 0, null); // 释放图形上下文对象,避免内存泄漏 graphics.dispose(); // 把处理好的logo图片再次设置给之前的logo图片对象 logoImage = image; // 开始把logo图片插入到二维码的中间位置 // 获取 Graphics2D 对象,用于后续在 bufferedImage 上绘制二维码和 logo 图片 Graphics2D graph = bufferedImage.createGraphics(); // 计算出 logo 图片在二维码中间的坐标点 (x, y),以便后续将 logo 图片插入到正确的位置。 int x = (CODE_WIDTH - logoWidth) / 2; int y = (CODE_HEIGHT - logoHeight) / 2; // 绘制缩放后的 logo 图片到二维码中间位置 graph.drawImage(logoImage, x, y, logoWidth, logoHeight, null); // 设置边框的线条粗细为 3 像素,并且设置线条是一个圆角矩形,6表示圆角的半径。并关闭资源 graph.setStroke(new BasicStroke(3f)); graph.draw(new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6)); graph.dispose(); } }
4、解析二维码
/** * 二维码解析 * * @author Anhui OuYang * @version 1.0 **/ public class QRCodeParsing { public static void main(String[] args) throws Exception { System.out.println("=========================二维码解析 Start========================="); parsingQRCode(new File("d://222.png")); System.out.println("=========================二维码解析 End========================="); } /*** * 二维码(QR_CODE)解析 * @param file 文件路径信息 */ public static void parsingQRCode(File file) throws IOException, NotFoundException { //创建一个图像数据缓冲区类(并读取二维码图片) BufferedImage bufferedImage = ImageIO.read(file); // 对图片信息的图像处理和分析 // 注意需要 zxing 库的版本 3.2.1 或更高版本才能使用,若没有则使用我下面定义的getRGBPixelData(BufferedImage image) BufferedImageLuminanceSource luminanceSource = new BufferedImageLuminanceSource(bufferedImage); // 若版本不够则使用这种方式 // RGBLuminanceSource luminanceSource = new RGBLuminanceSource(bufferedImage.getWidth(), // bufferedImage.getHeight(), getRGBPixelData(bufferedImage)); // 创建BinaryBitmap对象 // BinaryBitmap是二值化位图,将像素从RGB空间转换为黑白颜色空间 BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource)); // 设置解码参数 Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 设置解析的字符集 // 使用 MultiFormatReader 进行解码 MultiFormatReader formatReader = new MultiFormatReader(); formatReader.setHints(hints); // 设置解码一些参数 Result result = formatReader.decode(binaryBitmap); // 解码(解析binaryBitmap数据) // 打印一些信息 System.out.println("二维码解析图片的路径: " + file.getPath()); System.out.println("二维码解析图片中格式: " + result.getBarcodeFormat()); System.out.println("二维码解析图片中内容: " + result.getText()); } }
5、条形码
简单条形码(无文字)
public class GenerateBarcode { private static final Integer CODE_WIDTH = 300; // 基础属性:二维码宽度,单位像素 private static final Integer CODE_HEIGHT = 150; // 基础属性:二维码高度,单位像素 private static final Integer FRONT_COLOR = 0x000000; // 基础属性:二维码前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基础属性:二维码背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { //设置生成条形码的内容(注:条形码信息一定要按照格式,如随便一个商品上的条形码都行,但必须是EAN_13格式) String qrMessage = "6971483746515"; // EncodeHintType:指定和控制码生成器的一些参数的类 Map<EncodeHintType, Object> typeObjectHashMap = new HashMap<EncodeHintType, Object>(); // 设置编码 typeObjectHashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置容错等级 typeObjectHashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置边距,默认为5 typeObjectHashMap.put(EncodeHintType.MARGIN, 3); // MultiFormatWriter:用于写入条形码或二维码 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter .encode(qrMessage, BarcodeFormat.EAN_13, CODE_WIDTH, CODE_HEIGHT, typeObjectHashMap); // java.awt.image.BufferedImage:把条形码信息转换为图像信息 BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR); for (int x = 0; x < CODE_WIDTH; x++) { for (int y = 0; y < CODE_HEIGHT; y++) { bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); } } // javax.imageio.ImageIO 将图片信息写出到文件 ImageIO.write(bufferedImage, "png", new FileOutputStream("d://222.png")); } }
条形码(含文字)
/** * 一个简单的条形码生成 * * @author Anhui OuYang * @version 1.0 **/ public class GenerateBarcode { private static final Integer CODE_WIDTH = 300; // 基础属性:二维码宽度,单位像素 private static final Integer CODE_HEIGHT = 150; // 基础属性:二维码高度,单位像素 private static final Integer FRONT_COLOR = 0x000000; // 基础属性:二维码前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基础属性:二维码背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { // 条形码底部内容 String bottomStr = "123456"; // 条形码左上角内容 //String topLeftStr = name.length() < 11 ? name : name.substring(0, 11); String topLeftStr = "ceshi"; // 条形码右上角内容 String topRightStr = "2024-11-4"; // 生成条形码 BufferedImage barCodeImage = create(bottomStr, 250, 50); BufferedImage withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 250, 150, 10, 14); ImageIO.write(withWords, "png", new FileOutputStream("d://222.png")); barCodeImage = create(bottomStr, 350, 70); withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 350, 210, 14, 20); ImageIO.write(withWords, "png", new FileOutputStream("d://333.png")); barCodeImage = create(bottomStr, 500, 100); withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 500, 300, 20, 28); ImageIO.write(withWords, "png", new FileOutputStream("d://444.png")); } /** * 生成简单条形码(无文字) * * @param content * @param width * @param height * @return */ public static BufferedImage create(String content, int width, int height) { // 定义位图矩阵BitMatrix BitMatrix matrix = null; try { // 定义二维码参数 Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(3); // 设置编码 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置容错等级 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置边距,默认为5 hints.put(EncodeHintType.MARGIN, 3); // 使用code_128格式进行编码生成条形码 MultiFormatWriter writer = new MultiFormatWriter(); matrix = writer.encode(content, BarcodeFormat.CODE_128, width, height, hints); } catch (WriterException e) { e.printStackTrace(); //throw new RuntimeException("条形码内容写入失败"); } return MatrixToImageWriter.toBufferedImage(matrix); } /** * 生成条形码(含文字) * **************************************************** * ---------------------------------------------- * | 2023-06-10 10:55 | * | | * | 商品名称 /超出不显示/ | * | | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | 13800000000 | * ---------------------------------------------- * =================================================== * 1、日期:顶部右侧 * 2、商品名称:居中 * 3、条形码:商品名称下方,且居中 * 4、条码内容:条形码下方,且居中 * ***************************************************** * * @param codeImage 条形码图片 * @param bottomStr 底部文字 * @param titleStr 标题文字 * @param topRightStr 右上角文字 * @param pictureWidth 图片宽度 * @param pictureHeight 图片高度 * @param margin 边距 * @param fontSize 字体大小 * @return 条形码图片 */ private static BufferedImage createWithWords( BufferedImage codeImage, String bottomStr, String titleStr, String topRightStr, int pictureWidth, int pictureHeight, int margin, int fontSize) { BufferedImage picImage = new BufferedImage(pictureWidth, pictureHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = picImage.createGraphics(); // 抗锯齿 setGraphics2D(g2d); // 设置白色 setColorWhite(g2d, picImage.getWidth(), picImage.getHeight()); // 条形码默认居中显示 int codeStartX = (pictureWidth - codeImage.getWidth()) / 2; int codeStartY = (pictureHeight - codeImage.getHeight()) / 2 + 2 * margin; // 画条形码到新的面板 g2d.drawImage(codeImage, codeStartX, codeStartY, codeImage.getWidth(), codeImage.getHeight(), null); // 给条码上下各画一条线 // 设置颜色 g2d.setColor(Color.LIGHT_GRAY); int y1 = 2 * margin + codeImage.getHeight(); int y2 = 2 * margin + 2 * codeImage.getHeight(); g2d.drawLine(0, y1, pictureWidth, y1); g2d.drawLine(0, y2, pictureWidth, y2); // 画文字到新的面板 g2d.setColor(Color.BLACK); // 字体、字型、字号 g2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize)); // 文字与条形码之间的间隔 int wordAndCodeSpacing = 3; // 底部文字(居中) if (StringUtils.isNotEmpty(bottomStr)) { // 文字长度 int strWidth = g2d.getFontMetrics().stringWidth(bottomStr); // 文字X轴开始坐标 int strStartX = (pictureWidth - strWidth) / 2; if (strStartX < margin) { strStartX = margin; } // 文字Y轴开始坐标 int strStartY = codeStartY + codeImage.getHeight() + fontSize + wordAndCodeSpacing; // 画文字 g2d.drawString(bottomStr, strStartX, strStartY); } // 右上角文字 if (StringUtils.isNotEmpty(topRightStr)) { // 文字长度 int strWidth = g2d.getFontMetrics().stringWidth(topRightStr); // 文字X轴开始坐标 int strStartX = pictureWidth - strWidth - margin; // 文字Y轴开始坐标 int strStartY = margin + fontSize; // 画文字 g2d.drawString(topRightStr, strStartX, strStartY); } // 标题文字(居中) if (StringUtils.isNotEmpty(titleStr)) { if (titleStr.length() > 11) { titleStr = titleStr.substring(0, 11); } // 字体、字型、字号 int fs = (int) Math.ceil(fontSize * 1.5); g2d.setFont(new Font("微软雅黑", Font.PLAIN, fs)); // 文字长度 int strWidth = g2d.getFontMetrics().stringWidth(titleStr); // 文字X轴开始坐标 int strStartX = (pictureWidth - strWidth) / 2; if (strStartX < margin) { strStartX = margin; } // 文字Y轴开始坐标 int strStartY = codeStartY - margin; // 画文字 g2d.drawString(titleStr, strStartX, strStartY); } g2d.dispose(); picImage.flush(); return picImage; } /** * 设置 Graphics2D 属性 (抗锯齿) * * @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制 */ private static void setGraphics2D(Graphics2D g2d) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); g2d.setStroke(s); } /** * 设置背景为白色 * * @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制 */ private static void setColorWhite(Graphics2D g2d, int width, int height) { g2d.setColor(Color.WHITE); // 填充整个屏幕 g2d.fillRect(0, 0, width, height); // 设置笔刷 g2d.setColor(Color.BLACK); } }
解析条形码
以上就是Java zxing实现生成并解析二维码与条形码的详细内容,更多关于Java zxing解析二维码与条形码的资料请关注脚本之家其它相关文章!