Java 实现 URL 转二维码功能:完整教程(含图片压缩与实战案例)
·
Java 实现 URL 转二维码功能:完整教程(含图片压缩与实战案例)
在日常开发中,二维码作为信息快速传递的载体被广泛应用,比如通过 URL 生成二维码实现网页快速访问、文件下载等场景。本文将基于 Java 语言,结合成熟的二维码生成库,实现从 URL 到二维码的完整流程,包括二维码生成、图片尺寸调整(等比例压缩),并提供可直接复用的实战代码。
一、技术选型
核心依赖库
生成二维码的核心是 ZXing(Zebra Crossing)库,它是 Google 开源的多格式 1D/2D 条码图像处理库,支持 QR Code、Data Matrix 等多种条码类型,且使用简单、兼容性强。
依赖引入(Maven/Gradle)
Maven 依赖
<!-- ZXing 核心依赖 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
Gradle 依赖
implementation 'com.google.zxing:core:3.4.1'
implementation 'com.google.zxing:javase:3.4.1'
二、核心功能实现
本文将实现两个核心功能:
- URL 生成二维码:将指定 URL 编码为二维码图片并保存到本地;
- 二维码图片压缩:支持等比例/固定尺寸调整二维码图片大小,保证图片清晰度。
1. 工具类完整代码
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 javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Java URL 转二维码工具类(含图片压缩功能)
* @author 开发者名称
* @date 2025-11-06
*/
public class QrCodeUtils {
/**
* 生成二维码核心方法
* @param content 二维码内容(支持 URL、文本等)
* @param savePath 二维码图片保存路径(含文件名,如:D:/qrcode/test.png)
*/
public static void generateQrCode(String content, String savePath) {
// 1. 配置二维码参数
int width = 400; // 原始二维码宽度(像素)
int height = 400; // 原始二维码高度(像素)
String format = "png"; // 二维码图片格式(支持 png、jpg 等)
// 2. 二维码高级配置(容错级别、编码格式、边框宽度)
Map<EncodeHintType, Object> hints = new HashMap<>();
// 容错级别:L(7%) < M(15%) < Q(25%) < H(30%),M 级别平衡容错与密度
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
// 字符编码:避免中文/特殊字符乱码
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 边框宽度:0-4(0 表示无边框)
hints.put(EncodeHintType.MARGIN, 2);
try {
// 3. 生成二维码矩阵(核心步骤)
BitMatrix bitMatrix = new MultiFormatWriter().encode(
content,
BarcodeFormat.QR_CODE,
width,
height,
hints
);
// 4. 保存二维码到指定路径
File qrCodeFile = new File(savePath);
// 确保父目录存在(避免路径不存在报错)
if (!qrCodeFile.getParentFile().exists()) {
qrCodeFile.getParentFile().mkdirs();
}
MatrixToImageWriter.writeToPath(bitMatrix, format, qrCodeFile.toPath());
System.out.println("二维码生成成功!保存路径:" + savePath);
} catch (WriterException | IOException e) {
System.err.println("二维码生成失败!");
e.printStackTrace();
}
}
/**
* 调整 BufferedImage 大小(支持等比例压缩/固定尺寸)
* @param source 原始图片 BufferedImage 对象
* @param targetW 目标宽度(像素)
* @param targetH 目标高度(像素)
* @param keepRatio 是否保持等比例(true:等比例,false:固定尺寸)
* @return 调整后的 BufferedImage 对象
*/
public static BufferedImage resizeBufferedImage(BufferedImage source, int targetW, int targetH, boolean keepRatio) {
// 1. 计算缩放比例
double scaleX = (double) targetW / source.getWidth(); // 宽度缩放比例
double scaleY = (double) targetH / source.getHeight(); // 高度缩放比例
// 2. 若保持等比例,取最小缩放比例(避免图片拉伸)
if (keepRatio) {
scaleX = Math.min(scaleX, scaleY);
scaleY = scaleX;
// 重新计算目标尺寸(等比例后的实际尺寸)
targetW = (int) Math.round(source.getWidth() * scaleX);
targetH = (int) Math.round(source.getHeight() * scaleY);
}
// 3. 创建目标图片 BufferedImage 对象
BufferedImage targetImage;
int imageType = source.getType();
// 处理自定义图片类型(避免类型不兼容)
if (imageType == BufferedImage.TYPE_CUSTOM) {
ColorModel colorModel = source.getColorModel();
WritableRaster raster = colorModel.createCompatibleWritableRaster(targetW, targetH);
boolean alphaPremultiplied = colorModel.isAlphaPremultiplied();
targetImage = new BufferedImage(colorModel, raster, alphaPremultiplied, null);
} else {
targetImage = new BufferedImage(targetW, targetH, imageType);
}
// 4. 高质量缩放图片(使用 Graphics2D 保证清晰度)
Graphics2D graphics2D = targetImage.createGraphics();
// 设置渲染提示:抗锯齿、高质量缩放
graphics2D.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
);
graphics2D.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
// 执行缩放绘制
graphics2D.drawRenderedImage(
source,
AffineTransform.getScaleInstance(scaleX, scaleY)
);
graphics2D.dispose(); // 释放资源
return targetImage;
}
/**
* 读取本地图片为 BufferedImage 对象
* @param imagePath 图片本地路径
* @return BufferedImage 对象
* @throws IOException 图片读取异常
*/
public static BufferedImage readImage(String imagePath) throws IOException {
return ImageIO.read(new FileInputStream(imagePath));
}
/**
* 保存 BufferedImage 为本地图片
* @param image 要保存的 BufferedImage 对象
* @param savePath 保存路径(含文件名)
* @param format 图片格式(png/jpg 等)
* @throws IOException 图片保存异常
*/
public static void saveImage(BufferedImage image, String savePath, String format) throws IOException {
File saveFile = new File(savePath);
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}
ImageIO.write(image, format, saveFile);
System.out.println("图片保存成功!路径:" + savePath);
}
}
2. 关键方法解析
(1)二维码生成 generateQrCode 方法
- 参数配置:通过
Map<EncodeHintType, Object>配置二维码的容错级别、编码格式、边框宽度,其中:ERROR_CORRECTION:容错级别越高,二维码越抗污损,但密度越大(推荐 M 级别);CHARACTER_SET:指定 UTF-8 编码,避免 URL 中含特殊字符(如中文、参数符号)时乱码;MARGIN:边框宽度,0 表示无白边,2-4 为常用值。
- 核心逻辑:通过
MultiFormatWriter.encode()生成BitMatrix(二维码矩阵),再通过MatrixToImageWriter.writeToPath()将矩阵写入本地文件。
(2)图片压缩 resizeBufferedImage 方法
- 等比例压缩:当
keepRatio=true时,取宽度和高度缩放比例的最小值,确保图片不会拉伸,同时计算实际目标尺寸; - 高质量渲染:使用
Graphics2D并设置RenderingHints,保证缩放后的图片清晰度,避免出现模糊、锯齿等问题; - 类型兼容:处理
TYPE_CUSTOM类型图片,避免因图片类型不兼容导致的报错。
三、实战案例:URL 生成二维码并压缩
场景需求
将 URL(如 https://www.baidu.com/DocxView?entrustMsgId=xxx)生成二维码,保存到本地后,将图片压缩为 100x100 像素(等比例),用于网页展示或小程序使用。
测试代码
public class QrCodeTest {
public static void main(String[] args) {
// 1. 配置基础参数
String entrustMsgId = "MSG20251106001"; // 业务ID(示例)
String otherDatabaseName = "doc_db"; // 数据库名称(示例)
String baseImagePath = "D:/qrcode/"; // 图片保存根路径
String urlPrefix = "https://www.baidu.com/DocxView?entrustMsgId=";
String fullUrl = urlPrefix + entrustMsgId; // 完整 URL
// 2. 生成二维码文件名(避免重复)
String qrCodeFileName = entrustMsgId + "-" + otherDatabaseName + ".png";
String qrCodeSavePath = baseImagePath + qrCodeFileName; // 二维码保存路径
String compressedSavePath = baseImagePath + "compressed_" + qrCodeFileName; // 压缩后保存路径
try {
// 步骤1:生成原始二维码
QrCodeUtils.generateQrCode(fullUrl, qrCodeSavePath);
// 步骤2:读取原始二维码图片
BufferedImage originalImage = QrCodeUtils.readImage(qrCodeSavePath);
// 步骤3:等比例压缩为 100x100 像素
BufferedImage compressedImage = QrCodeUtils.resizeBufferedImage(originalImage, 100, 100, true);
// 步骤4:保存压缩后的图片
QrCodeUtils.saveImage(compressedImage, compressedSavePath, "png");
} catch (Exception e) {
System.err.println("URL 转二维码并压缩失败!");
e.printStackTrace();
}
}
}
执行结果
- 本地路径
D:/qrcode/下会生成两个文件:MSG20251106001-doc_db.png:原始 400x400 像素二维码;compressed_MSG20251106001-doc_db.png:压缩后 100x100 像素二维码(等比例,无拉伸)。
- 扫描二维码可直接跳转到目标 URL(
https://www.baidu.com/DocxView?entrustMsgId=MSG20251106001)。
四、常见问题与注意事项
1. 二维码生成失败?
- 检查
savePath路径是否合法(如是否有权限写入),工具类已添加mkdirs()自动创建父目录; - 确保 URL 格式正确,避免含非法字符(可通过
URLEncoder.encode()对 URL 编码后再生成二维码); - 检查 ZXing 依赖是否引入成功,版本是否兼容(推荐 3.5.0+)。
2. 压缩后图片模糊?
- 避免将小尺寸图片放大(如 100x100 放大到 400x400),会导致像素拉伸;
- 生成原始二维码时可适当增大尺寸(如 600x600),再压缩到目标尺寸,清晰度更高;
- 确保
resizeBufferedImage方法中启用了RenderingHints.KEY_RENDERING和KEY_ANTIALIASING。
3. 中文 URL 乱码?
- 生成二维码前,对中文 URL 进行 UTF-8 编码:
String fullUrl = urlPrefix + URLEncoder.encode(entrustMsgId, "UTF-8"); - 确保
generateQrCode方法中CHARACTER_SET配置为UTF-8。
五、功能扩展建议
- 添加 Logo:在二维码中心添加企业/产品 Logo,增强品牌识别度(需处理 Logo 大小,避免遮挡二维码信息);
- 内存流生成:不保存本地文件,直接生成
InputStream或Base64编码,用于网络传输(如接口返回二维码图片); - 自定义颜色:修改二维码的前景色(默认黑色)和背景色(默认白色),通过
MatrixToImageConfig实现; - 批量生成:支持多 URL 批量生成二维码,通过循环调用
generateQrCode方法实现。
六、总结
本文基于 Java + ZXing 库实现了 URL 转二维码的完整流程,包含二维码生成、等比例压缩、图片读写等核心功能,代码可直接复用在实际项目中。通过灵活配置二维码参数和图片压缩策略,可满足不同场景(如网页展示、打印、移动端识别)的需求。如果需要进一步扩展功能(如添加 Logo、Base64 编码),可基于本文工具类进行二次开发。
希望本文对你有所帮助,如有问题或优化建议,欢迎在评论区交流!
更多推荐

所有评论(0)