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 討論

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