zoukankan      html  css  js  c++  java
  • java(spring boot)实现二维码生成(可以插入中间log和底部文字)

    1.创建一个spring boot项目(非必须):

    项目结构:
    在这里插入图片描述
    2.导入maven依赖:

    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>com.google.zxing</groupId>
    			<artifactId>core</artifactId>
    			<version>3.4.0</version>
    		</dependency>
    		<dependency>
    			<groupId>com.google.zxing</groupId>
    			<artifactId>javase</artifactId>
    			<version>3.4.0</version>
    		</dependency>
    

    3.编码实现:

    QrcodeUtil工具类:

    /**
     * 二维码工具类
     * 
     * @author jinghx
     *
     */
    public class QrcodeUtil {
    	private QrcodeUtil() {
    
    	}
    
    	/**
    	 * 默认编码方式
    	 */
    	public static final String DEFAULT_CHARSET = "UTF-8";
    	/**
    	 * 默认二维码图片格式
    	 */
    	public static final String DEFAULT_SUBFIX = "PNG";
    
    	/**
    	 * 生成二维码默认宽度
    	 */
    	public static final int DEFAULT_WIDTH = 250;
    	/**
    	 * 生成二维码默认高度
    	 */
    	public static final int DEFAULT_HEIGHT = 300;
    	/**
    	 * 默认二维码中间log宽度
    	 */
    	public static final int DEFAULT_LOG_WIDTH = 50;
    	/**
    	 * 默认二维码中间log高度
    	 */
    	public static final int DEFAULT_LOG_HEIGHT = 50;
    	/**
    	 * 生成二维码默认保存位置
    	 */
    	public static final String DEFAULT_QRCODE_PATH = System.getProperty("user.dir") + "\" + "qrCode." + DEFAULT_SUBFIX;
    	/**
    	 * log默认路径
    	 */
    	public static final String DEFAULT_LOG_PATH = QrcodeUtil.class.getClassLoader().getResource("log/log.jpg")
    			.getPath();
    
    	/**
    	 * 由字符串生成二维码BufferedImage对象
    	 * 
    	 * @param content 字符串内容
    	 * @param width   二维码宽度,如果为空或小于等于0采用默认宽度
    	 * @param height  二维码高度,如果为空或小于等于0采用默认高度
    	 * @return
    	 */
    	private static BufferedImage createQrCodeBufferedImage(String content, Integer width, Integer height)
    			throws Exception {
    		BufferedImage resultImage = null;
    		if (!StringUtils.isEmpty(content)) {
    			Map<EncodeHintType, Object> hints = new HashMap<>();
    			hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHARSET);// 指定字符编码为UTF-8
    			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 指定二维码的纠错等级为中级
    			hints.put(EncodeHintType.MARGIN, 2);// 设置图片的边距
    
    			QRCodeWriter writer = new QRCodeWriter();
    			width = width != null && width > 0 ? width : DEFAULT_WIDTH;
    			height = height != null && height > 0 ? height : DEFAULT_HEIGHT;
    
    			BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
    			// 写到字节数据中
    			// MatrixToImageWriter.writeToStream(bitMatrix, DEFAULT_SUBFIX, os);
    			// resultImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
    			// ImageIO.write(resultImage, DEFAULT_SUBFIX, os);
    
    			// 写到文件中
    			// MatrixToImageWriter.writeToPath(bitMatrix, DEFAULT_SUBFIX,
    			// Paths.get(DEFAULT_PATH));
    
    			resultImage = new BufferedImage(bitMatrix.getWidth(), bitMatrix.getHeight(), BufferedImage.TYPE_INT_RGB);
    			for (int x = 0; x < width; x++) {
    				for (int y = 0; y < height; y++) {
    					resultImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF008000 : 0xFFFFFFFF);// 0xFF000000 黑色 0xFF008000 绿色
    				}
    			}
    		}
    		return resultImage;
    	}
    
    	/**
    	 * 由字符串生成base64格式的简单二维码
    	 * 
    	 * @param content      字符串内容
    	 * @param width        二维码宽度,如果为空或小于等于0采用默认宽度
    	 * @param height       二维码高度,如果为空或小于等于0采用默认高度
    	 * @param isSaveToPath 是否保存到文件中
    	 * @return
    	 */
    	public static String productQrCodeString(String content, Integer width, Integer height, boolean isSaveToPath) {
    		String resultImage = "";
    		if (!StringUtils.isEmpty(content)) {
    			try {
    				BufferedImage image = createQrCodeBufferedImage(content, width, height);
    				if (image != null) {
    					ByteArrayOutputStream os = new ByteArrayOutputStream();
    					ImageIO.write(image, DEFAULT_SUBFIX, os);
    					resultImage = "data:image/" + DEFAULT_SUBFIX + ";base64,"
    							+ new String(Base64.getEncoder().encode(os.toByteArray()));
    					if (isSaveToPath) {
    						ImageIO.write(image, DEFAULT_SUBFIX, new FileOutputStream(DEFAULT_QRCODE_PATH));
    					}
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    		return resultImage;
    	}
    
    	/**
    	 * 由字符串生成base64格式的复杂二维码
    	 * 
    	 * @param content        字符串内容
    	 * @param width          二维码宽度,如果为空或小于等于0采用默认宽度
    	 * @param height         二维码高度,如果为空或小于等于0采用默认高度
    	 * @param isSaveToPath   是否保存到文件中
    	 * @param logPath        log图片的路径
    	 * @param isFixedLogSize 是否固定log图片大小
    	 * @param text           二维码底部文本内容
    	 * @return
    	 */
    	public static String productQrCodeWithLog(String content, Integer width, Integer height, boolean isSaveToPath,
    			String logPath, boolean isFixedLogSize, String text) {
    		String resultImage = "";
    		if (!StringUtils.isEmpty(content)) {
    			try {
    				width = width != null && width > 0 ? width : DEFAULT_WIDTH;
    				height = height != null && height > 0 ? height : DEFAULT_HEIGHT;
    				BufferedImage image = createQrCodeBufferedImage(content, width, height);
    				if (image != null) {
    					ByteArrayOutputStream os = new ByteArrayOutputStream();
    					insertImageAndText(image, width, height, StringUtils.isEmpty(logPath) ? DEFAULT_LOG_PATH : logPath,
    							isFixedLogSize, text);
    					ImageIO.write(image, DEFAULT_SUBFIX, os);
    					resultImage = "data:image/" + DEFAULT_SUBFIX + ";base64,"
    							+ new String(Base64.getEncoder().encode(os.toByteArray()));
    					if (isSaveToPath) {
    						ImageIO.write(image, DEFAULT_SUBFIX, new FileOutputStream(DEFAULT_QRCODE_PATH));
    					}
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    		return resultImage;
    	}
    
    	/**
    	 * 插入LOGO
    	 *
    	 * @param source         二维码图片
    	 * @param width          二维码宽度,如果为空或小于等于0采用默认宽度
    	 * @param height         二维码高度,如果为空或小于等于0采用默认高度
    	 * @param imgPath        LOGO图片地址
    	 * @param isFixedLogSize 是否固定二维码中间log图标大小
    	 * @param text           二维码底部文本内容
    	 * @throws Exception
    	 */
    	private static void insertImageAndText(BufferedImage source, Integer width, Integer height, String imgPath,
    			boolean isFixedLogSize, String text) throws Exception {
    		File file = new File(imgPath);
    		if (!file.exists()) {
    			System.err.println("" + imgPath + "   该文件不存在!");
    			return;
    		}
    		Image src = ImageIO.read(new File(imgPath));
    		int lwidth = src.getWidth(null);
    		int lheight = src.getHeight(null);
    		if (isFixedLogSize || lwidth >= width || lheight >= height) { // 固定LOGO大小
    			if (lwidth > width) {
    				lwidth = DEFAULT_LOG_WIDTH;
    			}
    			if (lheight > height) {
    				lheight = DEFAULT_LOG_HEIGHT;
    			}
    			Image image = src.getScaledInstance(lwidth, lheight, Image.SCALE_SMOOTH);
    			BufferedImage tag = new BufferedImage(lwidth, lheight, 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 = (width - lwidth) / 2;
    		int y = (height - lheight) / 2;
    		graph.drawImage(src, x, y, lwidth, lheight, null);
    		Shape shape = new RoundRectangle2D.Float(x, y, lwidth, lheight, 6, 6);
    		graph.setStroke(new BasicStroke(3f));
    		graph.draw(shape);
    
    		if (!StringUtils.isEmpty(text)) {
    			int fontStyle = 1;
    			int fontSize = 12; //
    			// 计算文字开始的位置(居中显示)
    			// x开始的位置:(图片宽度-字体大小*字的个数)/2
    			int startX = (width - (fontSize * text.length())) / 2;
    			// y开始的位置:图片高度-(图片高度-图片宽度)/2
    			int startY = height - (height - width) / 2;
    			graph.setColor(Color.BLUE);
    			graph.setFont(new Font(null, fontStyle, fontSize)); // 字体风格与字体大小 graph.drawString(text, startX, startY);
    			graph.drawString(text, startX, startY);
    		}
    
    		graph.dispose();
    	}
    
    	/**
    	 * 解码二维码内容
    	 * 
    	 * @param file
    	 * @return
    	 * @throws Exception
    	 */
    	public static String decode(File file) throws Exception {
    		BufferedImage image;
    		image = ImageIO.read(file);
    		if (image == null) {
    			return null;
    		}
    		BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
    		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    		Result result;
    		Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
    		hints.put(DecodeHintType.CHARACTER_SET, DEFAULT_CHARSET);
    		result = new MultiFormatReader().decode(bitmap, hints);
    		String resultStr = result.getText();
    		return resultStr;
    	}
    
    	public static void main(String[] args) throws Exception {
    		System.out.println(decode(new File(DEFAULT_QRCODE_PATH)));
    	}
    }
    

    编写一个测试用的Controller类:

    @RestController
    @RequestMapping("/qrcode")
    public class QrCodeController {
    
    	/**
    	 * 生成简单的字符串二维码
    	 * 
    	 * @param content
    	 * @return
    	 */
    	@PostMapping("/simpleCode")
    	public String productQrCode(String content) {
    		return QrcodeUtil.productQrCodeString(content, null, null, true);
    	}
    
    	/**
    	 * 生成带有log和底部字符串的二维码
    	 * 
    	 * @param content
    	 * @return
    	 */
    	@PostMapping("/codePlus")
    	public String productQrCodeWithLogAndText(String content, String bottomText) {
    		return QrcodeUtil.productQrCodeWithLog(content, null, null, true, null, true, bottomText);
    	}
    
    }
    

    编写一个简单的html页面qrCode.html,实时查看二维码生成效果:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>生成二维码</title>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    </head>
    <body>
    	<div style="float: left">
    		<div>
    			<input id="strContent" type="text" width="500px"
    				placeholder="输入二维码想显示的内容">
    			<button onclick="getSimpleQrcode()">点击显示简单二维码</button>
    		</div>
    		<div>
    			<img id="simpleQrCode" />
    		</div>
    
    	</div>
    	<div style="float: left; padding-left: 20px;">
    		<div>
    			<input id="logContent" type="text" width="500px"
    				placeholder="输入二维码想显示的内容"> <input id="bottomText"
    				type="text" width="300px" placeholder="二维码底部文字,可不填">
    			<button onclick="getComplexQrcode()">点击显示带log二维码</button>
    		</div>
    		<div>
    			<img id="complexQrCode" />
    		</div>
    	</div>
    </body>
    <script type="text/javascript">
    	/**
    	 * 通过ajax请求获取base64编码格式的二维码
    	 */
    	function getpQrcode(url, param, imgId) {
    		$.ajax({
    			url : url,
    			cache : false,
    			type : 'POST',
    			data : param,
    			async : true,
    			dataType : 'text',
    			error : function(event, XMLHttpRequest, ajaxOptions, thrownError) {
    				console.log(event);
    				console.log(XMLHttpRequest);
    				console.log(ajaxOptions);
    				console.log(thrownError);
    			},
    			success : function(data) {
    				$("#" + imgId).prop('src', data);
    			}
    		});
    	}
    	/**
    	 *简单二维码
    	 */
    	function getSimpleQrcode() {
    		let url = "qrcode/simpleCode";
    		let param = {
    			'content' : $("#strContent").prop('value')
    		};
    		let imgId = "simpleQrCode";
    		getpQrcode(url, param, imgId);
    	}
    	/**
    	 *复杂二维码
    	 */
    	function getComplexQrcode() {
    		let url = "qrcode/codePlus";
    		let param = {
    			'content' : $("#logContent").prop('value'),
    			'bottomText' : $("#bottomText").prop('value')
    		};
    		let imgId = "complexQrCode";
    		getpQrcode(url, param, imgId);
    	}
    </script>
    </html>
    

    整个工程就是依赖google的二维码工具包来进行二维码的生成,代码的注释比较详细了,这里就不再做过多的赘述,运行工程:

    访问:http://localhost:8080/qrcode.html
    在这里插入图片描述
    可以在对应的input框中输入你想要生成的二维码内容,点击旁边的按钮即可生成(二维码颜色可以参考 颜色名称 RGB 对照表 设置):
    在这里插入图片描述
    同时工程目录下会保存一张最新生成的二维码图片:
    在这里插入图片描述

    一颗安安静静的小韭菜。文中如果有什么错误,欢迎指出。
  • 相关阅读:
    my first android test
    VVVVVVVVVV
    my first android test
    my first android test
    my first android test
    ini文件
    ZZZZ
    Standard Exception Classes in Python 1.5
    Python Module of the Week Python Module of the Week
    my first android test
  • 原文地址:https://www.cnblogs.com/c-Ajing/p/13448345.html
Copyright © 2011-2022 走看看