一个二维码生成和读取工具类

1、前言

ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。
该项目可实现的条形码编码和解码。

2、新一个 maven建工程,引入zxing依赖

<dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.3.3</version>
</dependency>
    
<dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>javase</artifactId>
       <version>3.3.3</version>
</dependency>

3、引入辅助类MatrixToImageWriter

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import com.google.zxing.common.BitMatrix;

/**
 * 二维码的生成需要借助MatrixToImageWriter类,该类是由Google提供的,可以将该类直接拷贝到源码中使用
 */
public class MatrixToImageWriter {
    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    private MatrixToImageWriter() {
    }

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }

    public static void writeToFile(BitMatrix matrix, String format, File file)
            throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, file)) {
            throw new IOException("Could not write an image of format "
                    + format + " to " + file);
        }
    }

    public static void writeToStream(BitMatrix matrix, String format,
                                     OutputStream stream) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format " + format);
        }
    }
}

4、二维码生成、读取工具类Utils

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


public class Utils {
	
	// 默认是黑色
	private static final int QRCOLOR = 0xFF000000; 
	// 背景颜色
    private static final int BGWHITE = 0xFFFFFFFF;
    // 是绿色 
    public static final int QRCOLOR_GREEN = 0x05A01D; 
 
    // 二维码宽
    private static final int WIDTH = 400; 
    // 二维码高
    private static final int HEIGHT = 400; 
    
    /**
            * 用于设置QR二维码参数
     */
    private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
        private static final long serialVersionUID = 1L;
 
        {
        	// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
            put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置编码方式
            put(EncodeHintType.CHARACTER_SET, "utf-8");
            put(EncodeHintType.MARGIN, 0);
        }
    };
	
    /**
           * 根据传入的字符串生成一个简单的二维码
     * @param qrContent
     * @param outputFile
     * @throws WriterException
     * @throws IOException
     */
	public static void drawSimpleQRCode(String qrContent, File outputFile) throws WriterException, IOException{
        BitMatrix bitMatrix = new MultiFormatWriter().encode(qrContent,BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
        MatrixToImageWriter.writeToFile(bitMatrix, "jpg", outputFile);
    }
	
	
	 /**
           * 生成带logo的二维码图片
     * @param imageFile 二维码中心小图标
     * @param outputFile 生成的二维码文件
     * @param content 二维码内容
     * @param note  二维码底部文字描述
     * @param QRCOLOR 二维码背景颜色
     * @return
     */
    public static void drawImageQRCode(File imageFile, File outputFile, String content, String note,int QRCOLOR) throws Exception{
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
            BitMatrix bm = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
 
            // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
            for (int x = 0; x < WIDTH; x++) {
                for (int y = 0; y < HEIGHT; y++) {
                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
                }
            }
 
            int width = image.getWidth();
            int height = image.getHeight();
            if (imageFile.exists()) {
                // 构建绘图对象
                Graphics2D g = image.createGraphics();
                // 读取Logo图片
                BufferedImage logo = ImageIO.read(imageFile);
                // 开始绘制logo图片
                g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
                g.dispose();
                logo.flush();
            }
 
            // 自定义文本描述
        if (note != null && !note.equals("")) {
            // 新的图片,把带logo的二维码下面加上文字
            BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D outg = outImage.createGraphics();
            // 画二维码到新的面板
            outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
            // 画文字到新的面板
            outg.setColor(Color.BLACK);
            outg.setFont(new Font("楷体", Font.BOLD, 30)); // 字体、字型、字号
            int strWidth = outg.getFontMetrics().stringWidth(note);
            if (strWidth > 399) {
                // //长度过长就截取前面部分
                // 长度过长就换行
                String note1 = note.substring(0, note.length() / 2);
                String note2 = note.substring(note.length() / 2, note.length());
                int strWidth1 = outg.getFontMetrics().stringWidth(note1);
                int strWidth2 = outg.getFontMetrics().stringWidth(note2);
                outg.drawString(note1, 200 - strWidth1 / 2, height + (outImage.getHeight() - height) / 2 + 12);
                BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
                Graphics2D outg2 = outImage2.createGraphics();
                outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                outg2.setColor(Color.BLACK);
                outg2.setFont(new Font("宋体", Font.BOLD, 30)); // 字体、字型、字号
                outg2.drawString(note2, 200 - strWidth2 / 2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
                outg2.dispose();
                outImage2.flush();
                outImage = outImage2;
            } else {
                outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12); // 画文字
                }
                outg.dispose();
                outImage.flush();
                image = outImage;
            }
 
            image.flush();
 
            ImageIO.write(image, "png", outputFile); 
    }
	
	
	public static void main(String[] args)throws Exception {
	    // 1、生成一个简单的二维码(只有文字内容)
		//File outputFile = new File("D:/test/test.jpg");
		//drawSimpleQRCode("我爱祖国",outputFile);
		
		// 2、生成一个文字内容为“我爱祖国”,底部文字描述为“我爱祖国的蓝天”,中心小图标为“123.”
		File imageFile = new File("D:/test01/123.png");
		File outputFile = new File("D:/test01/test123.jpg");
		String content = "我爱祖国";
		String note = "我爱祖国的蓝天";
		drawImageQRCode(imageFile, outputFile, content, note,BLACK);
	}

}

二维码生成方法说明:
1、根据字符串生成一个简单的二维码 (drawSimpleQRCode)
在这里插入图片描述
2、根据字符串、图片、文字描述生成一个有中心图标、底部有文字说明、背景颜色为黑色的的二维码(drawImageQRCode)
在这里插入图片描述
3、根据字符串、图片、文字描述生成一个有中心图标、底部有文字说明、背景颜色为绿色的二维码
在这里插入图片描述

5、读取二维码信息

/**
  * 识别二维码
 */
    public static void QRReader(File file) throws IOException, NotFoundException {
        MultiFormatReader formatReader = new MultiFormatReader();
        //读取指定的二维码文件
        BufferedImage bufferedImage =ImageIO.read(file);
        BinaryBitmap binaryBitmap= new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
        //定义二维码参数
        Map  hints= new HashMap<String,String>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        com.google.zxing.Result result = formatReader.decode(binaryBitmap, hints);
        //输出相关的二维码信息
        System.out.println("解析结果:"+result.toString());
        System.out.println("二维码格式类型:"+result.getBarcodeFormat());
        System.out.println("二维码文本内容:"+result.getText());
        bufferedImage.flush();
    }

	public static void main(String[] args)throws Exception {
		File outputFile = new File("D:/test01/test123.jpg");
		QRReader(outputFile);
	}

在这里插入图片描述

发布了122 篇原创文章 · 获赞 152 · 访问量 112万+

猜你喜欢

转载自blog.csdn.net/ytangdigl/article/details/104711123