二维码生成与套图二维码

时间:2024-04-14 20:59:39

1:首先感谢这篇文章真正的博客:https://w.cnblogs.com/Reborn-yuan/p/10409693.html

如下代码都是根据这篇文章改进了一些地方

2:首先还是导入jar包

<!--普通二维码生成jar包-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>

3:配置写入器以及测试主方法(默认生成地址不在C盘,这里的原因是我的电脑,系统是家庭版C盘不然轻易访问所以改成了E)

package com.ff.demo;

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 org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


public class GenerateQRcode {

    /**
     *生成二维码主方法入口
     * @param qrdata 二维码的内容
     * @param generatePath 生成的路径
     * @param photoName 生成后名称
     * @param imageType 图片的类型
     */
    public static void getQRcode(String qrdata,String generatePath,String photoName,String imageType) {
        try {
            if(StringUtils.isEmpty(generatePath)){
                 generatePath = "E:\\";// 二维码默认
            }
            if(StringUtils.isEmpty(photoName)){
                photoName = UUID.randomUUID().toString();// 二维码的图片名
            }
            if(StringUtils.isEmpty(imageType)){
                imageType = "jpg";// 图片类型
            }
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = multiFormatWriter.encode(qrdata, BarcodeFormat.QR_CODE, 400, 400, hints);
            File file1 = new File(generatePath, photoName + "." + imageType);
            if (!file1.exists() && !file1.isDirectory()) {
                file1.mkdirs();
            }
            MatrixToImageWriter.writeToFile(bitMatrix, imageType, file1);
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
* 简要构造器 * @param qrdata 二维码内容 * @param photoName 二维码名称(可以不填,写null 生成后名称就是uuid)
*/ public static void getQRcode(String qrdata,String photoName) { getQRcode(qrdata,null,photoName,null); } } class MatrixToImageWriter { private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; 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); } } }

3:新建枚举类,用来放一些常用的图片类型 也可以不用这一步,直接在测试的时候,图片类型直接写成String类型的,如:“JPG”

public enum  ImageTypeEnum {
JPG("jpg"),
PNG("png"),
BMP("bmp"),
TIF("tif"),
GIF("gif"),
PCX("pcx"),
TGA("tga"),
FPX("fpx"),
SVG("scg"),
PSD("psd"),
CDR("cdr"),
EXIF("exif");
private String type; public String getType() { return type; } ImageTypeEnum(String type) { this.type = type; } }

4:测试生成二维码

@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() throws Exception {
GenerateQRcode.getQRcode("https://www.cnblogs.com/aiqingbi-aifeifei/",null,"测试",ImageTypeEnum.GIF.getType());
GenerateQRcode.getQRcode("https://www.cnblogs.com/aiqingbi-aifeifei/","E:\\","测试名称","png");
}
}

结果:

 

 

 

 

 

二:二维码中间套图片等

1:首先还是导入jar包,与上面的包是一致的

2:配置写入器

package com.ff.demo;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable;
import java.util.UUID;

public class GenerateUtils {
private static final String CHARSET = "utf-8";
private static final String FORMAT_NAME = "jpg";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
// LOGO宽度
private static final int WIDTH = 100;
// LOGO高度
private static final int HEIGHT = 100;

private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
if (imgPath == null || "".equals(imgPath)) {
return image;
}
// 插入图片
GenerateUtils.insertImage(image, imgPath, needCompress);
return image;
}

/**
* 插入LOGO
*
* @param source 二维码图片
* @param imgPath LOGO图片地址
* @param needCompress 是否压缩
* @throws Exception
*/
private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
File file = new File(imgPath);
if (!file.exists()) {
System.err.println("" + imgPath + " 该文件不存在!");
return;
}
Image src = ImageIO.read(new File(imgPath));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > WIDTH) {
width = WIDTH;
}
if (height > HEIGHT) {
height = HEIGHT;
}
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}

/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param imgPath LOGO地址
* @param destPath 存放目录
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static String getLogoQRcode(String content, String imgPath, String destPath, boolean needCompress,String photoName,String imageType)
throws Exception {

BufferedImage image = GenerateUtils.createImage(content, imgPath, needCompress);

// 随机生成二维码图片文件名
if(StringUtils.isEmpty(destPath)){
destPath = "E:\\";// 二维码默认
}
if(StringUtils.isEmpty(photoName)){
photoName = UUID.randomUUID().toString();// 二维码的图片名
}
if(StringUtils.isEmpty(imageType)){
imageType = "jpg";// 图片类型
}
mkdirs(destPath);
String file = photoName+"."+imageType;
ImageIO.write(image, FORMAT_NAME, new File(destPath,file ));
return destPath + file;
}

/**
* 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
*
* @author lanyuan Email: mmm333zzz520@163.com
* @date 2013-12-11 上午10:16:36
* @param destPath 存放目录
*/
public static void mkdirs(String destPath) {
File file = new File(destPath);
// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
}

public static String getLogoQRcode(String content, String imgPath, boolean needCompress)
throws Exception {
String re = getLogoQRcode(content,imgPath,null,needCompress,null,null);
return re;
}
}

 

3:到这一步就可以测试了

@SpringBootTest
class DemoApplicationTests {

    @Test
    void contextLoads() throws Exception {
        GenerateQRcode.getQRcode("https://www.cnblogs.com/aiqingbi-aifeifei/",null,"测试",ImageTypeEnum.GIF.getType());
        GenerateQRcode.getQRcode("https://www.cnblogs.com/aiqingbi-aifeifei/",null,"测试名称","png");
    }

//测试logo方法 @Test
void getQR() throws Exception{
//第一个路径是logo图片,第二个是生成的路径 生成的路径在简要方法中可以不写,默认在我电脑是E盘 GenerateUtils.getLogoQRcode(
"https://www.cnblogs.com/aiqingbi-aifeifei/","E:\\MyPhotos\\mongchong.jpg","E:\\",true,"测试套图",ImageTypeEnum.JPG.getType());
GenerateUtils.getLogoQRcode(
"https://www.cnblogs.com/aiqingbi-aifeifei/","E:\\MyPhotos\\mongchong.jpg",true); } }

结果如下:

 

 

 

至此,生成测试已经完毕,大家可以参考一下,代码复制后,改个包名,就可以直接生成了,但是代码中的E盘,可以参考本机的盘,写个C  D应该都没问题