java提高zxing二维码识别率

网上找到的一些示例都不太行,我自己写了一个。并且在每个生成地方添加了图片输出,不需要的可以删除。

 /**
     * 获取图片信息(裁剪图片)
     * @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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值