Java生成二维码快速上手

简介

本文主要介绍使用Java生成二维码,可以实现自定义二维码名称以及二维码内容,也可以设置生成二维码的长和宽,根据测试结论内容越多从而生成二维码的密度越高,同时优化了二维码的纠错能力以及防止乱码,也优化了二维码的留白问题,可实现二维码四周无留白或者留白的间距,废话不多说,接下来看一下如何实现的吧!Go,Go,Go~~~

生成二维码

引入pom依赖

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.4.1</version>
    <scope>compile</scope>
</dependency>

封装工具类

方式一

将二维码输出到本地默认位置

public static void main(String[] args) throws WriterException, IOException {
        // 生成二维码图片到本地(方式一)
        String text = "二维码内容";
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        //定义map集合,用于存放二维码的一些其他设置
        Map<EncodeHintType, Object> map = Maps.newHashMap();
        //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
        //L:Low 7%   M:Middle 15%  Q:Quartereed 25%  H:High 30%
        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置编码,防止乱码
        map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        //设置留白
        map.put(EncodeHintType.MARGIN,0);
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
        Path file = FileSystems.getDefault().getPath("qrcode.png");
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
        System.out.println("二维码已生成:" + file.toAbsolutePath());
}

方式二

将二维码输出到本地默认位置

// 所引用的方法 在文章的下方    
public static void main(String[] args) throws WriterException, IOException {
        // 生成二维码图片到本地(方式二)
        String text = "二维码内容";
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        //定义map集合,用于存放二维码的一些其他设置
        Map<EncodeHintType, Object> map = Maps.newHashMap();
        //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
        //L:Low 7%   M:Middle 15%  Q:Quartereed 25%  H:High 30%
        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置编码,防止乱码
        map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        //设置留白
        map.put(EncodeHintType.MARGIN,0);
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
        BufferedImage bufferedImage = deleteWhite(bitMatrix);
//        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
        byte[] bytes = bufferedImageToByteArray(bufferedImage);
        MultipartFile multipartFile = FilesUtil.byteArrayToMultipartFile(bytes, "qrcode.png", "qrcode.png", ContentType.IMAGE_JPEG.toString());
        Path path = FileSystems.getDefault().getPath(multipartFile.getName());
        File file = path.toFile();
        multipartFile.transferTo(file);
        System.out.println("二维码已生成:" + path.toAbsolutePath());
    }

将二维码四周的白色边距去掉方法

/**
     * 将二维码四周的白色边距去掉
     * @param matrix 二维码对象
     * @return 二维码
     */
    private static BufferedImage deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;

        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1]))
                    resMatrix.set(i, j);
            }
        }

        int width = resMatrix.getWidth();
        int height = resMatrix.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, resMatrix.get(x, y) ? BLACK
                        : WHITE);
            }
        }
        return image;
    }

将BufferedImage转换为Byte数组方法

/**
     * 将BufferedImage转换为Byte数组
     * @param image BufferedImage对象
     * @return byte数组
     * @throws IOException io异常
     */
    public static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "png", outputStream);
        return outputStream.toByteArray();
    }

将byte数组转为MultipartFile文件对象

/**
     * 将byte数组转为MultipartFile文件对象
     * @param byteArray byte数组
     * @param fileName 文件名称
     * @param originalFilename 源文件名称
     * @param contentType 文件类型
     * @return MultipartFile文件对象
     */
    public static MultipartFile byteArrayToMultipartFile(byte[] byteArray, String fileName, String originalFilename, String contentType) {
        InputStream inputStream = new ByteArrayInputStream(byteArray);

        try {
            MultipartFile multipartFile = new MockMultipartFile(fileName, originalFilename, contentType, inputStream);
            return multipartFile;
        } catch (IOException e) {
            logger.error("byteArrayToMultipartFile ---fileName:{}  ---ex:{}", fileName, ExceptionUtils.getErrorStackTrace(e));
        }
        return null;
    }

二维码工具类

package com.uyaogui.common.core.util;

import com.google.common.collect.Maps;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.uyaogui.common.core.exception.ExceptionUtils;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

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

import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;

public class QRCodeUtils {

    private static final Logger logger = LoggerFactory.getLogger(QRCodeUtils.class);

    // 二维码大小(长、宽)
    private static final int QR_CODE_SIZE = 256;


    /**
     * 获取二维码文件
     * @param text 二维码内容
     * @param fileName 二维码文件名称
     * @return 二维码文件对象
     */
    public static MultipartFile getQRCodeMultipartFile(String text, String fileName){
        logger.info("getQRCodeMultipartFile ---text:{},fileName:{}", text, fileName);
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        //定义map集合,用于存放二维码的一些其他设置
        Map<EncodeHintType, Object> map = Maps.newHashMap();
        //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
        //L:Low 7%   M:Middle 15%  Q:Quartereed 25%  H:High 30%
        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置编码,防止乱码
        map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        //设置留白
        map.put(EncodeHintType.MARGIN,0);
        try {
            BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
            BufferedImage bufferedImage = deleteWhite(bitMatrix);
            byte[] bytes = bufferedImageToByteArray(bufferedImage);
            return FilesUtil.byteArrayToMultipartFile(bytes, fileName, fileName, ContentType.IMAGE_JPEG.toString());
        } catch (Exception e) {
            logger.error("getQRCodeMultipartFile ---text:{},fileName:{}  ---ex:{}", text, fileName, ExceptionUtils.getErrorStackTrace(e));
        }
        return null;
    }

    public static void main(String[] args) throws WriterException, IOException {
//        // 生成二维码图片到本地(方式一)
//        String text = "二维码内容";
//        QRCodeWriter qrCodeWriter = new QRCodeWriter();
//        //定义map集合,用于存放二维码的一些其他设置
//        Map<EncodeHintType, Object> map = Maps.newHashMap();
//        //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
//        //L:Low 7%   M:Middle 15%  Q:Quartereed 25%  H:High 30%
//        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//        //设置编码,防止乱码
//        map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//        //设置留白
//        map.put(EncodeHintType.MARGIN,0);
//        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
//        Path file = FileSystems.getDefault().getPath("qrcode.png");
//        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
//        System.out.println("二维码已生成:" + file.toAbsolutePath());

        // 生成二维码图片到本地(方式二)
        String text = "二维码内容";
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        //定义map集合,用于存放二维码的一些其他设置
        Map<EncodeHintType, Object> map = Maps.newHashMap();
        //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
        //L:Low 7%   M:Middle 15%  Q:Quartereed 25%  H:High 30%
        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置编码,防止乱码
        map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        //设置留白
        map.put(EncodeHintType.MARGIN,0);
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
        BufferedImage bufferedImage = deleteWhite(bitMatrix);
//        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
        byte[] bytes = bufferedImageToByteArray(bufferedImage);
        MultipartFile multipartFile = FilesUtil.byteArrayToMultipartFile(bytes, "qrcode.png", "qrcode.png", ContentType.IMAGE_JPEG.toString());
        Path path = FileSystems.getDefault().getPath(multipartFile.getName());
        File file = path.toFile();
        multipartFile.transferTo(file);
        System.out.println("二维码已生成:" + path.toAbsolutePath());
    }


    /**
     * 将二维码四周的白色边距去掉
     * @param matrix 二维码对象
     * @return 二维码
     */
    private static BufferedImage deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;

        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1]))
                    resMatrix.set(i, j);
            }
        }

        int width = resMatrix.getWidth();
        int height = resMatrix.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, resMatrix.get(x, y) ? BLACK
                        : WHITE);
            }
        }
        return image;
    }

    /**
     * 将BufferedImage转换为Byte数组
     * @param image BufferedImage对象
     * @return byte数组
     * @throws IOException io异常
     */
    public static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "png", outputStream);
        return outputStream.toByteArray();
    }
}

文件对象转换工具类

package com.uyaogui.common.core.util;

import com.uyaogui.common.core.exception.ExceptionUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class FilesUtil {

    private static final Logger logger = LoggerFactory.getLogger(FilesUtil.class);

    /**
     * 根据网络URL获取文件流
     * @param url 网络URL
     * @return 文件流
     */
    public static byte[] getFileStream(String url){
        try {
            URL httpUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)httpUrl.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(10 * 1000);
            conn.setReadTimeout(10 * 1000);
            InputStream inStream = conn.getInputStream();//通过输入流获取图片数据
            byte[] btImg = readInputStream(inStream);//得到图片的二进制数据
            inStream.close();
            return btImg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件对象转MultipartFile对象
     * @param file 文件
     * @return MultipartFile对象
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItem fileItem = createFileItem(file);
        return new CommonsMultipartFile(fileItem);
    }

    /**
     * 根据File对象创建FileItem对象
     * @param file File
     * @return FileItem对象
     */
    public static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }


    /**
     * 得到文件的二进制数据,以二进制封装得到数据,具有通用性
     *
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度,如果为-1,代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

	/**
	 * MultipartFile 转 File
	 *
	 * @param multipartFile
	 * @throws Exception
	 */
	public static File multipartFileToFile(MultipartFile multipartFile) {
		File file = null;
		//判断是否为null
		if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
			return file;
		}
		//MultipartFile转换为File
		InputStream ins = null;
		OutputStream os = null;
		try {
			ins = multipartFile.getInputStream();
			file = new File(multipartFile.getOriginalFilename());
			os = new FileOutputStream(file);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ins != null) {
				try {
					ins.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return file;
	}

    /**
     * 将byte数组转为MultipartFile文件对象
     * @param byteArray byte数组
     * @param fileName 文件名称
     * @param originalFilename 源文件名称
     * @param contentType 文件类型
     * @return MultipartFile文件对象
     */
    public static MultipartFile byteArrayToMultipartFile(byte[] byteArray, String fileName, String originalFilename, String contentType) {
        InputStream inputStream = new ByteArrayInputStream(byteArray);

        try {
            MultipartFile multipartFile = new MockMultipartFile(fileName, originalFilename, contentType, inputStream);
            return multipartFile;
        } catch (IOException e) {
            logger.error("byteArrayToMultipartFile ---fileName:{}  ---ex:{}", fileName, ExceptionUtils.getErrorStackTrace(e));
        }
        return null;
    }

}

结束语

以上就是本次介绍的二维码生成工具类,有需要的朋友们直接Ctrl+C、Ctrl+V


作者:筱白爱学习!!

欢迎关注转发评论点赞沟通,您的支持是筱白的动力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱白爱学习

你的鼓励将是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值