Java中识别二维码并且提高二维码的识别率

我们在Java开发的时候,发现对二维码的识别是不足的。所以我们需要提高识别率。

第一步。识别图片二维码。准备相应的jar包。我们在gradle+idea中开发。

compile group: 'com.google.zxing', name: 'core', version: '3.3.0'
compile group: 'com.google.zxing', name: 'javase', version: '3.3.0'

zxing是google提供的生成二维码和识别二维码的jar包。

第二步:准备QRCodeGenerator 


import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
 * 二维码相关操作
 * Created by hongming.zhao on 2019/11/20.
 */
public class QRCodeGenerator {

    private static final int margin = 0;
    private static final String QR_CODE_IMAGE_PATH = "C:/photo/MyQRCode.png";

    private static void generateQRCodeImage(String text, int width, int height, String filePath) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();

        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);

        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    /**
     * 生成二维码(黑白色)
     * @param text  扫描二维码的内容
     * @param width  宽
     * @param height  长
     * @return
     * @throws Exception
     */
    public static BufferedImage qRCodeCommon(String text, int width, int height)throws Exception{

        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,防止中文乱码
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级
        hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return MatrixToImageWriter.toBufferedImage(bitMatrix);
    }
    /**
     * 解析二维码解析,此方法是解析Base64格式二维码图片
     * baseStr:base64字符串,data:image/png;base64开头的
     */
    public static String deEncodeByBase64(String baseStr) {
        String content = null;
        BufferedImage image;
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b=null;
        try {
            int i = baseStr.indexOf("data:image/png;base64,");
            baseStr = baseStr.substring(i+"data:image/png;base64,".length());//去掉base64图片的data:image/png;base64,部分才能转换为byte[]

            b = decoder.decodeBuffer(baseStr);//baseStr转byte[]
            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(b);//byte[] 转BufferedImage
            image = ImageIO.read(byteArrayInputStream);
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
            System.out.println("图片中内容:  ");
            System.out.println("content: " + result.getText());
            content = result.getText();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        return content;
    }
    /**
     * 解析二维码,此方法解析一个路径的二维码图片
     * path:图片路径
     */
    public static String deEncodeByPath(String path) {
        String content = null;
        BufferedImage image;
        try {
            image = ImageIO.read(new File(path));
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
            System.out.println("图片中内容:  ");
            System.out.println("content: " + result.getText());
            content = result.getText();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
        return content;
    }

    public static void main(String[] args) {
        try {
            //String info="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1575540267760&di=e8b961051b3ab58538e092c5e1be87a1&imgtype=0&src=http%3A%2F%2Fg.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2Fb8389b504fc2d56263697b8ce51190ef76c66c6a.jpg";
            String info="C:/photo/6.jpg";
            deEncodeByPath(info);
            //generateQRCodeImage("This is my first QR Code", 350, 350, QR_CODE_IMAGE_PATH);
            //qRCodeCommon("This is my first QR Code", 350, 350);
        } catch (Exception e) {
            System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage());
        }

    }


}

第三步:在controll层中添加

@ApiOperation(value = "生成的登录二维码",notes = "生成的登录二维码",httpMethod = "GET")
    @RequestMapping(value = "/proCode",method = RequestMethod.GET)
    public void  createQRCode(HttpServletResponse httpServletResponse)throws Exception{
        HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
        System.out.println("生成二维码!");
        //生成唯一ID
        String uuid = request.getParameter("uuid");
        tokes.add(uuid);
        logger.info("uuid=====>"+uuid);
        //二维码内容,在手机上登录的是一个是否在手机上确认登录的地址(在app内)。
        String url=environment.getProperty("mfw.authority.appAffirmurl");

        String encoderContent=url+uuid+"?date="+(new Date()).getTime();

        logger.info("perfactUrl====>"+encoderContent);
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        BufferedImage twoDimensionImg = new QRCodeGenerator().qRCodeCommon(encoderContent,350,350);
        ImageIO.write(twoDimensionImg, "jpg", jpegOutputStream);
        response.addHeader("Content-Disposition", "attachment;filename=" + new String((uuid+".jpg").getBytes()));
        byte[] bys = jpegOutputStream.toByteArray();
        response.addHeader("Content-Length", "" + bys.length);
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream =
                httpServletResponse.getOutputStream();
        responseOutputStream.write(bys);
        responseOutputStream.flush();
        responseOutputStream.close();
        websocketModel wm = new websocketModel();
        wm.setType("overdue");
        wm.setUid(uuid);
        myWebSocket.sendInfo(wm,uuid);//向前端发送消息
    }

 

 

 

 

 

 

参考:提高zxing对二维码的识别率

          zxing 二维码生成深度定制

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值