Itext5生成高质量、易识别、适合小尺寸标签打印的二维码
高质量、易识别、小尺寸二维码生成
1.增大二维码的原始尺寸(例如 1000 x 1000 或更大),再缩放为 PDF 所需的大小。这样可以保留更多像素细节,提高识别率。
2.降低容错级别到 L 或 M,如果你的内容不是特别长或复杂的话,这样能减少密集度。
3.优化缩放方式:
• 使用 BufferedImage 放大或缩小时,避免图片模糊。
• 尽量在原始生成阶段保持高分辨率。
需要引入zxing
<!-- zxing -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.0</version>
</dependency>
/**
* 生成二维码
* @param content 字符串(二维码内容)
* @param cb PDF模版文件
* @throws Exception
*/
private void generateQRcode(String content, PdfContentByte cb) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 容错级别调为 L
hints.put(EncodeHintType.MARGIN, 0); // 去掉白边,实际没起作用
int originalSize = 1000; // 生成更大的二维码
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, originalSize, originalSize, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
// 创建高分辨率的 BufferedImage
BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = qrImage.createGraphics();
// 设置背景为白色
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
// 绘制二维码
graphics.setColor(Color.BLACK);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (bitMatrix.get(x, y)) {
qrImage.setRGB(x, y, 0xFF000000);
}
}
}
graphics.dispose(); // 释放图形资源
// 将高质量二维码写入字节流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(qrImage, "png", byteArrayOutputStream);
// 从字节流中读取为 iText Image 对象
Image qrcodeImage = PngImage.getImage(byteArrayOutputStream.toByteArray());
// 缩放图片到适合 PDF 的大小
qrcodeImage.scaleAbsolute(274, 271);
// 设置位置
qrcodeImage.setAbsolutePosition(417, 13);
cb.addImage(qrcodeImage);
}
二维码裁剪白色边框
hints.put(EncodeHintType.MARGIN, 0)去掉白边代码,实际没起作用
InputStream templateStream = getClass().getResourceAsStream("/template/Autumntemplate.pdf");
PdfReader reader = new PdfReader(templateStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
// 获取第1页的 PdfContentByte
PdfContentByte cb = stamper.getOverContent(1);
// 传入 PdfContentByte 对象,附加二维码
generateQRcode(qrContent, cb);
/**
* 生成二维码并附加到PDF上
* @param content
* @param cb
* @throws Exception
*/
private void generateQRcode(String content, PdfContentByte cb) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 容错级别调为 L
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
// 去掉白边,实际没有去掉
hints.put(EncodeHintType.MARGIN, 0);
// 生成更大的二维码
int originalSize = 1000;
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, originalSize, originalSize, hints);
// 创建一个与二维码大小相同的 BufferedImage
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 填充二维码图像
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
qrImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
// 裁剪掉白色边距
BufferedImage croppedImage = cropWhiteBorder(qrImage);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(croppedImage, "png", byteArrayOutputStream);
Image qrcodeImage = PngImage.getImage(byteArrayOutputStream.toByteArray());
// 设置图片大小,最终二维码大小和位置在这里设置
qrcodeImage.scaleAbsolute(274, 271);
// 设置位置
qrcodeImage.setAbsolutePosition(417, 13);
cb.addImage(qrcodeImage);
}
/**
* 去二维码白边
* @param image
* @return
*/
private BufferedImage cropWhiteBorder(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
int left = width, right = 0, top = height, bottom = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// 如果是黑色像素
if (image.getRGB(x, y) == 0xFF000000) {
if (x < left) left = x;
if (x > right) right = x;
if (y < top) top = y;
if (y > bottom) bottom = y;
}
}
}
// 根据检测到的边界裁剪
return image.getSubimage(left, top, right - left + 1, bottom - top + 1);
}
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~


浙公网安备 33010602011771号