网上找到的一些示例都不太行,我自己写了一个。并且在每个生成地方添加了图片输出,不需要的可以删除。
/**
* 获取图片信息(裁剪图片)
* @param image 附件
* @param fileName 文件名
* @param maxScaleFactor 最多裁剪因子
* @return
* @throws IOException
*/
private static Result getCroppingImageText(BufferedImage image, String fileName, int maxScaleFactor) throws IOException {
// 灰度化处理
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = grayImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose(); // 释放资源
int width = grayImage.getWidth();
int height = grayImage.getHeight();
MultiFormatReader multiFormatReader = new MultiFormatReader();
Map<DecodeHintType, Object> hints = getMultiFormatReaderMap();
//for循环遍历所有缩放因子
for (int i = 1; i <= maxScaleFactor ; i++) {
for (int j = 1; j <= maxScaleFactor ; j++) {
//计算缩放后的宽度和高度(相除再向上取整,只取整数)
int scaleWidth = (int) Math.ceil(width / (double) i);
int scaleHeight = (int) Math.ceil(height / (double) j);
//创建缩放后的图片
// 逐块裁剪并尝试解析二维码
for (int y = 0; y < height; y += scaleHeight) {
for (int x = 0; x < width; x += scaleWidth) {
int x1 = Math.min(x + scaleWidth, width);
int y1 = Math.min(y + scaleHeight, height);
log.info("x:{},y:{},x1:{},y1:{}",x,y,x1,y1);
BufferedImage tile = grayImage.getSubimage(x, y, x1 - x, y1 - y);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(tile)));
File filePath = new File("D://"+fileName.substring(0, fileName.lastIndexOf("."))+"-"+i+"-"+j+"分割.png");
ImageIO.write(tile, "png", filePath);
try {
// 尝试解析该块
Result result = multiFormatReader.decode(binaryBitmap, hints);
log.info("result:{}",result);
if (result != null) {
return result; // 解析成功,立即返回结果
}
} catch (NotFoundException e) {
log.info("分割识别失败");
// 捕获解析失败的异常,继续尝试下一块
//放大倍数
try {
Result result = getScaleImageText(tile, fileName, 3,i+""+j);
if (result != null) {
return result; // 解析成功,立即返回结果
}
} catch (Exception ex) {
}
}
}
}
}
}
throw new IOException("二维码在图像中未找到");
}
/**
* 创建 MultiFormatReader 对象
* @return
*/
private static Map<DecodeHintType, Object> getMultiFormatReaderMap() {
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
return hints;
}
/**
* 获取图片信息(放大图片)
* @param image
* @return
* @throws IOException
* @throws NotFoundException
*/
private static Result getScaleImageText(BufferedImage image, String fileName, int maxScaleFactor,String j) throws IOException, NotFoundException {
log.info("开始放大图片");
// 灰度化处理
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = grayImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose(); // 释放资源
MultiFormatReader multiFormatReader = new MultiFormatReader();
Map<DecodeHintType, Object> hints = getMultiFormatReaderMap();
// 尝试不同放大倍数的图像解析
for (int scaleFactor = 2; scaleFactor <= maxScaleFactor; scaleFactor++) {
log.info("放大倍数:"+scaleFactor);
BufferedImage scaledImage = scaleImage(grayImage, scaleFactor);
// 使用 ZXing 解析放大后的图像
LuminanceSource source = new BufferedImageLuminanceSource(scaledImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
File filePath = new File("D://"+fileName.substring(0, fileName.lastIndexOf("."))+"-"+j+"-"+scaleFactor+"放大.png");
ImageIO.write(scaledImage, "png", filePath);
try {
// 尝试解析该块
Result result = multiFormatReader.decode(bitmap, hints);
if (result != null) {
return result; // 解析成功,立即返回结果
}
} catch (NotFoundException e) {
// 捕获解析失败的异常,继续尝试下一块
}
}
throw new IOException("二维码在图像中未找到");
}
/**
* 图像放大
* @param originalImage 原始图像
* @param scaleFactor 放大比例
* @return
*/
public static BufferedImage scaleImage(BufferedImage originalImage, int scaleFactor) {
int width = originalImage.getWidth() * scaleFactor;
int height = originalImage.getHeight() * scaleFactor;
// 创建一个新的空白图像,放大尺寸后的
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// 使用 Graphics2D 进行图像缩放
Graphics2D g2d = scaledImage.createGraphics();
// 确保高质量的缩放
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.drawImage(originalImage, 0, 0, width, height, null);
g2d.dispose();
return scaledImage;
}