二维码的生成与解析-Java代码(zxing方式)

二维码的生成与解析-Java代码(zxing方式)

突然 就想试试二维码,然后在网上找了好久,终于让我找到了。并且生成了这个二维码:
亚索的二维码

有两种方法可以产生二维码:

(1). QRCode
QRCode应该和zxing差不多,但是我只找到了生成二维码的jar包, 没有解析二维码的jar包的资源,所以我就放弃了它。

(2). zxing
zxing相关的jar包的获取途径:点击此处

在导入了 core-3.4.0 和 javase-3.4.0之后,再使用以下的Java代码(该代码是从 这里 参考的):

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.decoder.ErrorCorrectionLevel;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author amorjoo.ncu
 * @description 生成、解析二维码的代码 ZXing方式(https://www.jianshu.com/p/6015822d44c7)
 * @version 1.8
 * @date 2019/10/10 16:22
 */
public class QRCodeService {
    private static final String CHARSET = "UTF-8";

    private QRCodeService() {}

    public static QRCodeService instance = new QRCodeService();

    /**
     * 生成普通的二维码
     * @param contents      二维码中储存的信息
     * @param width         生成二维码的宽度
     * @param height        生成二维码的高度
     * @param qrFile        目标文件
     * @return              返回生成的二维码 - "png"格式
     */
    public File encode(String contents, int width, int height, File qrFile) {
        // 生成条形码时的一些配置
        Map<EncodeHintType, Object> hints = new HashMap<>();
        // 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)等级越高,纠错率越高,但存储的信息越少
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        // 指定内容所使用字符集编码
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        //设置一下边距,默认是5
        hints.put(EncodeHintType.MARGIN, 2);

        BitMatrix bitMatrix;
        try {
            OutputStream out = new FileOutputStream(qrFile);
            // 生成二维码
            bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
            // 二维码的格式 - png
            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return qrFile;
    }

    /**
     * 将普通二维码变成带logo的二维码
     * @param qrFile        普通二维码
     * @param logoFile      logo的图片
     * @param newQrFile     目标文件
     * @return              返回带logo的二维码 - "png"格式
     */
    public File encodeWithLogo(File qrFile, File logoFile, File newQrFile) {
        OutputStream os = null ;
        try {
            Image image = ImageIO.read(qrFile) ;
            int width = image.getWidth(null) ;
            int height = image.getHeight(null) ;
            BufferedImage bufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) ;
            // BufferedImage bufferImage =ImageIO.read(image) ;
            Graphics2D g2 = bufferImage.createGraphics();
            g2.drawImage(image, 0, 0, width, height, null) ;
            int matrixWidth = bufferImage.getWidth();
            int matrixHeight = bufferImage.getHeight();

            // 读取Logo图片
            BufferedImage logo = ImageIO.read(logoFile);
            // 开始绘制图片
            g2.drawImage(logo,matrixWidth / 5 * 2,matrixHeight / 5 * 2,
                    matrixWidth / 5, matrixHeight / 5, null);//绘制
            BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(stroke);// 设置笔画对象
            // 指定弧度的圆角矩形
            RoundRectangle2D.Float round = new RoundRectangle2D.Float((float) matrixWidth / 5 * 2,
                    (float) matrixHeight / 5 * 2,(float) matrixWidth / 5,
                    (float) matrixHeight / 5,20,20);
            g2.setColor(Color.white);
            g2.draw(round);// 绘制圆弧矩形

            // 设置logo 有一道灰色边框
            BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
            g2.setStroke(stroke2);// 设置笔画对象
            RoundRectangle2D.Float round2 = new RoundRectangle2D.Float((float) matrixWidth / 5 * 2 + 2,
                    (float) matrixHeight / 5 * 2 + 2,(float) matrixWidth / 5 - 4,
                    (float) matrixHeight / 5 - 4,20,20);
            g2.setColor(new Color(128,128,128));
            g2.draw(round2);// 绘制圆弧矩形

            g2.dispose();

            bufferImage.flush() ;
            os = new FileOutputStream(newQrFile) ;
            JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os) ;
            en.encode(bufferImage) ;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return newQrFile ;
    }

    /**
     * 解析二维码(ZXing)
     * @param qrFile        二维码文件
     * @return              返回解析出的字符串,若为null,则文件不存在
     */
    public String decode(File qrFile) {
        BufferedImage image = null;
        Result result = null;
        try {
            image = ImageIO.read(qrFile);
            if (image == null) {
                System.out.println("the decode image may be not exit.");
                return null;
            }
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            Map<DecodeHintType, Object> hints = new HashMap<>();
            hints.put(DecodeHintType.CHARACTER_SET, CHARSET);

            result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        assert result != null;
        return result.getText() ;
    }
}

再让我们测试一下:

import java.io.File;

/**
 * @author amorjoo.ncu
 * @description //TODO
 * @version 1.8
 * @date 2019/10/10 17:06
 */
public class Test_QRCode {
    public static void main(String[] args) {
        //test_Encode_1();
        test_Encode_2();
    }

    public static void test_Encode_1() {
        File file = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\QRCode.png");

        if(file.exists()) {
            System.out.println(file);

            file = QRCodeService.instance.encode("http://www.baidu.com",500,500,file);
            System.out.println(file != null ? "操作成功!" : "操作失败!");
        }else {
            System.out.println("文件不存在!");
        }
    }

    public static void test_Encode_2() {
        File oldFile = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\QRCode.png");
        File logo = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\yasuo.png");
        File newFile = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\new.png");

        if(oldFile.exists()) {
            oldFile = QRCodeService.instance.encode("壮士E去不复返!",1000,1000,oldFile);
            newFile = QRCodeService.instance.encodeWithLogo(oldFile, logo, newFile);
            System.out.println(newFile != null ? "快乐成功!" : "快乐失败!");
        }else {
            System.out.println("文件不存在!");
        }
    }
}

运行代码之后你就会发现,图片变成了二维码。

另外,我试了一下,用其他类型的文件作为方法中的参数,好像不能成功,所以,最好参数里使用相同格式的文件(不排除偶然性)。

如果你是一个懒癌晚期患者,也可以戳 --------这里-------- 百度网盘提取码:2168 来获得jar包和java代码。

希望这篇文章能对你有帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值