java生成二维码(带logo和不带logo两种,二维码上方显示文字)

可以生成带logo或者不带logo的二维码

一、准备(导入jar包)

方法一:如果是用maven:则在pom.xml文件中添加如下配置

<!--二维码依赖包-->
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>core</artifactId>
	<version>3.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>javase</artifactId>
	<version>3.4.0</version>
</dependency>

方法二:如果是普通的web项目,则在WEB-INF/lib下添加如下jar包

csdn下载链接:https://download.csdn.net/download/qq_16758997/11978559

可以自行到maven仓库下载更新版本,搜索zxing(见下图)

方法三:普通的java项目则直接将方法二中下载的jar包放入项目中并添加classpath路径(不是系统环境变量)

二、实现代码

import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

/**
 * 二维码生成类
 */
public class QRcodeService {
	private static final String CHARSET = "utf-8";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;
 
    private static BufferedImage createImage(List<String> code, String content, String imgPath, boolean needCompress) throws Exception {
        Map<EncodeHintType, Object> hints = new Hashtable<>();
        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);
            }
        }

        //在二维码下方增加文字显示
        BufferedImage bi = new BufferedImage(width, height+20*code.size(), BufferedImage.TYPE_INT_RGB);//将高度增加20,在二维码下方增加一个区域显示文字
        Graphics2D g2 = bi.createGraphics();
        g2.setBackground(new Color(0xFF,0xFF,0xFF));
        g2.clearRect(0, 0, width, height);

        g2.drawImage(image, 0, 20*code.size(), width, height, null); //x,y为image图片的位置
        //设置生成图片的文字样式
        Font font = new Font("黑体", Font.BOLD, 17);
        g2.setFont(font);
        g2.setPaint(new Color(0x0,0x0,0x0));

        // 设置字体在图片中的位置 在这里是居中
        for(int i=0;i<code.size();){
            // 防止生成的文字带有锯齿
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            // 在图片上生成文字
            g2.drawString(code.get(i), 5, 20*++i); //x,y为文字的位置
        }

        image=bi;
        if (imgPath == null || "".equals(imgPath))
            return image;
        // 插入图片
        QRcodeService.insertImage(image, imgPath, needCompress, code);
        return image;
    }

    /**
     * 插入logo图标
     * @param source 二维码Image对象
     * @param imgPath logo路径
     * @param needCompress 是否需要缩小logo图标
     * @param code 
     * @throws Exception
     */
    private static void insertImage(BufferedImage source, String imgPath, boolean needCompress, List<String> code) 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;
            }
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    		Graphics g = image.getGraphics();
    		g.drawImage(src, 0, 0, width, height, null); // 绘制图
    		// 画边框
    		g.setColor(Color.BLACK);
    		g.drawRect(4, 4, width - 8, height - 8);
    		g.drawRect(5, 5, width - 10, height - 10);
            
            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+code.size()*20, width, height, null);//logo的位置可能需要调整
        Shape shape = new RoundRectangle2D.Float(x, y+code.size()*20, width, width, 6, 6);//阴影的位置可能需要调整
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

    /**
     * 生成包含logo的二维码
     * @param code 需要显示在二维码上方的list文字集合
     * @param content 二维码中包含的内容
     * @param imgPath logo图像地址
     * @param needCompress 是否需要缩小logo图标
     * @param fileUtil 保存文件的类对象
     * @return 保存后的文件路径
     * @throws Exception
     */
    public static String encode(List<String> code, String content, String imgPath, boolean needCompress, FileUtil fileUtil) throws Exception {
        BufferedImage image = QRcodeService.createImage(code, content, imgPath, needCompress);
        //获取当前时间并格式化
        String path=new SimpleDateFormat("yyyy/MM/dd hh:mm:ss").format(new Date());
        path=path.substring(0,10);
        //保存文件到磁盘
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "png", os);
        InputStream input = new ByteArrayInputStream(os.toByteArray());
        return fileUtil.writeFile(input, "D:/qrcode/"+path, path+".png");
    }

    /**
     * 不包含logo的二维码
     * @param code 需要显示在二维码上方的list字符串集合
     * @param content 二维码中的内容
     * @param fileUtil 保存文件的工具类
     * @return 保存成功之后的路径地址
     * @throws Exception
     */
    public static String encode(List<String> code, String content, FileUtil fileUtil) throws Exception {
    	return QRcodeService.encode(code, content, null, false, fileUtil);
    }
}
import java.io.*;

/**
 * 保存文件工具类
 */
public class FileUtil {
    /**
     * 保存文件对象
     * @param is 文件InputStream对象
     * @param target 文件目标
     * @throws IOException
     */
	public String writeFile(InputStream input, String path, String fileName) throws IOException {
		fileName=System.currentTimeMillis()+fileName.substring(fileName.indexOf("."));
        String filePath = verifyFolderExist(null, path, fileName);
        if (filePath == null) return filePath;
        writeFile(input, new File(filePath));
        return path + File.separator + fileName;
	}
	/**
	 * 校验文件夹path文件夹是否存在
	 * @param file
	 * @param path
	 * @param fileName
	 * @return
	 */
    public String verifyFolderExist(File file, String path, String fileName) {
        String folder_path = path;
        String filePath = folder_path + File.separator + fileName;
        if (file != null && file.getAbsolutePath().equals(filePath)) {
            return null;
        }
        File folder = new File(folder_path);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        return filePath;
    }
    /**
     * 写入文件
     * @param is
     * @param target
     * @throws IOException
     */
    public void writeFile(InputStream is, File target) throws IOException {
        OutputStream os = new FileOutputStream(target);
        byte[] bytes = new byte[1024 * 1024];
        int len = 0;
        while ((len = is.read(bytes, 0, bytes.length)) > 0) {
            os.write(bytes, 0, len);
        }
        is.close();
        os.close();
    }
}

三、测试代码

import java.util.*;

public class Test {
	public static void main(String[] args) throws Exception {
		List<String> showContent = new ArrayList<>();
		//二维码上没有显示内容则传递空的list集合即可
		showContent.add("名称:这是显示在二维码上的文字");
		showContent.add("编码:这是显示在二维码上的文字");
		//无logo的二维码
		String path = new QRcodeService().encode(showContent, "这是二维码中的内容", new FileUtil());
		System.out.println("无logo的二维码  "+path);
		//有logo的二维码
		path = new QRcodeService().encode(showContent,"这是二维码中的内容", "/C:/Users/yuye/Desktop/logo.png",true, new FileUtil());
		System.out.println("有logo的二维码  "+path);
	}
}

效果

完美

欢迎加群:517413713 讨论

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章