在Java后端服务或本地工具中,经常需要把订单号、链接或配置信息转成二维码方便移动端扫取。Zxing(ZXing)是Google开源的一维码与二维码处理库,社区活跃、API清晰,适合快速集成到Spring Boot或普通Java应用里。下面以QR Code为例,说明如何生成和解析二维码图片。

一、引入Zxing依赖
如果使用Maven构建项目,只需要在pom.xml里添加核心包即可。Zxing的com.google.zxing:core提供了编解码基础能力,javase模块则包含将矩阵转为图片、从图片读取矩阵的辅助类,建议一起引入。
依赖版本可以选择较新的稳定版,例如3.5.0以上。添加后刷新工程,就能在代码里使用QRCodeWriter、MatrixToImageWriter等类。注意不要混用差异过大的版本,否则可能出现MethodNotFound或二进制不兼容。
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.2</version>
</dependency>
二、生成二维码图片
生成过程分为三步:定义内容编码提示参数、调用QRCodeWriter生成BitMatrix、使用MatrixToImageWriter写出图片。关键参数包括字符集、纠错等级、边距。中文内容必须显式指定UTF-8,否则默认平台编码会导致扫码后出现乱码。
纠错等级分为L、M、Q、H,等级越高可承受的污损越多,但图形密度更大。普通展示用M即可;若二维码会被印在易磨损物料上,建议用Q或H。边距参数控制静区宽度,设为零可让图形充满画布,但部分老旧扫码器可能识别困难。
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
public class QrGenerator {
public static void generate(String text, int width, int height, Path outPath) throws WriterException, IOException {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.MARGIN, 1);
QRCodeWriter writer = new QRCodeWriter();
BitMatrix matrix = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToPath(matrix, "PNG", outPath);
}
}
上面方法把文本写入指定路径的PNG文件。如果想直接返回BufferedImage嵌入到Swing界面或HTTP响应,可改用MatrixToImageWriter.toBufferedImage(matrix)。这样无需落盘,适合接口实时出图。
三、解析二维码图片
解析是生成的逆过程:把图片加载为BufferedImage,转换为灰度LuminanceSource,经HybridBinarizer二值化得到BinaryBitmap,最后用QRCodeReader解码。环境光线不均或图片缩放会引入噪点,适当提高对比度有助于提升识别率。
读取时同样要指定字符集UTF-8,否则中文内容可能解析成问号。如果图片来源是摄像头帧,建议先做尺寸归一化,避免过大图拖慢解码。下面示例从本地文件读取并输出原文。
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class QrParser {
public static String parse(File imageFile) throws Exception {
BufferedImage image = ImageIO.read(imageFile);
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
}
}
四、常见坑点与优化建议
第一个常见问题是生成的二维码手机扫不出。多半是尺寸太小或边距为零导致静区不足,可以把宽高设为300以上、边距保留1到2个模块。第二个问题是解析报NotFoundException,通常是图片模糊或色彩空间为CMYK,转成RGB再试。
性能方面,若系统需高并发出码,可以复用QRCodeWriter实例,并将图片写入ByteArrayOutputStream后缓存。解析多图时,使用多线程分别处理不同BufferedImage,但注意MultiFormatReader并非线程安全,应每线程独立创建。掌握这些细节,就能在Java项目里稳定落地二维码功能。
| 场景 | 推荐纠错等级 | 建议尺寸 |
|---|---|---|
| 屏幕展示 | M | 240x240 |
| 印刷物料 | Q或H | 400x400以上 |
| 内网批量标签 | L | 160x160 |
五、小结
通过Zxing在Java中生成与解析二维码并不复杂,核心在于正确设置字符集与纠错参数,以及理解BitMatrix到图片、图片到BinaryBitmap的转换链路。把上述工具类封装为独立模块,就能在各类业务里快速复用。
后续可结合Spring MVC将生成接口暴露为REST端点,或把解析能力接入后台审核流。只要避开中文编码与静区过窄两个坑,基本可以满足绝大多数工程化需求。