注:本文用以解决实际生产需求,而非深入学习研究所用,如需深入请接入:QR Code API

一、引入pom依赖

		<dependency>
			<groupId>com.google.zxing</groupId>
			<artifactId>javase</artifactId>
			<version>${google.zxing.version}</version>
		</dependency>

		<dependency>
			<groupId>net.coobird</groupId>
			<artifactId>thumbnailator</artifactId>
			<version>${coobird.version}</version>
		</dependency>

二、编写生成所需基本方法

	/**
	 * 根据参数生成二维码链接内容
	 * @param params
	 * @return
	 */
	private static String getConent(QRParams params) {
		String url = params.getUrl();
		Long userid = params.getUserId();
		Map<String, Object> map = params.getParams();
		if (StringUtils.isBlank(url)) {
			//默认指向公司主页
			url = URL;
		}
		if (userid == null) {
			//默认以管理员身份生成
			userid = 1L;
		}

		StringBuilder sb = new StringBuilder();
		sb.append(url).append("?").append("userid=").append(userid);

		map.forEach((x,y)-> sb.append("&&").append(x).append("=").append(y));
		return sb.toString();
	}

	/**
	 * 返回一个 BufferedImage 对象
	 *
	 * @param content 二维码内容
	 * @param width   宽
	 * @param height  高
	 */
	private static BufferedImage toContentBufferedImage(String content, int width, int height) throws WriterException {
		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, HINTS);
		//默认画笔只支持黑色,这里手动添加onColor值,开启彩色画笔
		return MatrixToImageWriter.toBufferedImage(bitMatrix,new MatrixToImageConfig(2,-1));
	}


	/**
	 * 获取文件输入流
	 * @param dirPath
	 * @return
	 */
	private static InputStream getInputStream(String dirPath) {
		//利用资源加载器获取资源URL
		if (dirPath.contains(":")) {
			try {
				UrlResource resource = new UrlResource(dirPath);
				return resource.getInputStream();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
        //利用类资源加载器获取本地文件
		return QRCodeUtils.class.getResourceAsStream(dirPath);
	}

三、获取二维码

	/**
	 * 生成二维码不带水印
	 * @param params
	 * @param width
	 * @param height
	 * @param response
	 */
	public static void createQRCode(QRParams params, int width, int height, HttpServletResponse
		response) {
		createQRCodeWithLogo(params,null,width,height,response);
	}

	/**
	 * 生成带水印二维码
	 * @param params 二维码内容
	 * @param logoUrl logo 链接
	 */
	public static void createQRCodeWithLogo(QRParams params, String logoUrl, int width, int height, HttpServletResponse
		response) {

		response.setContentType("image/png");

		ServletOutputStream outputStream = null;
		try {
			outputStream = response.getOutputStream();
			// 根据toBufferedImage() 返回的 BufferedImage 创建图片构件对象
			Thumbnails.Builder<BufferedImage> builder = Thumbnails.of(toContentBufferedImage(getConent(params), width,
				height));
			// 将 logo 的尺寸设置为二维码的 30% 大小, 可以自己根据需求调节
			 if(StringUtils.isNotBlank(logoUrl)) {

				BufferedImage logoImage = Thumbnails.of(getInputStream(logoUrl)).forceSize((int) (width * 0.4), (int)
					(height * 0.4)).asBufferedImage();
				// 设置水印位置(居中), 水印图片 BufferedImage, 不透明度(1F 代表不透明)
				builder.watermark(Positions.CENTER, logoImage, 1F);
			}
			// 此处需指定图片格式, 否者报 Output format not specified 错误
			builder.scale(1F).outputFormat(FORMAT).toOutputStream(outputStream);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

四、测试

@RestController
@RequestMapping("/qrCode")
public class QRCodeController {

	/**
	 * todo 获取二维码(先用get测试。。后期改post)
	 * @param params
	 * @param response
	 */
	@GetMapping("/createQRCodeWithLogo")
	public void createQRCodeWithLogo(QRParams params, HttpServletResponse response) {
		//无水印
//		QRCodeUtils.createQRCode(params,QRCodeUtils.WIDTH,QRCodeUtils.HEIGHT,response);
		//本地加载水印
	//	QRCodeUtils.createQRCodeWithLogo(params,"/test.png", QRCodeUtils.WIDTH,QRCodeUtils.HEIGHT,response);
		//水印来自网络资源
		QRCodeUtils.createQRCodeWithLogo(params,QRCodeUtils.LOGO_URL, QRCodeUtils.WIDTH,QRCodeUtils.HEIGHT,response);
	}

}

效果: 

五、资源链接

传送门,走你!

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐