使用ZXing 生成二维码及带logo的二维码。
ZXing简介
ZXing是一款开源的优秀二维码编码&解码库,支持javase和Android集成, github地址:https://github.com/zxing/zxing。
效果图
maven依赖
com.google.zxing
core
3.3.0
com.google.zxing
javase
3.3.0
代码实现
1. QRCodeService
package apple.springmvc.zxing.service;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author Ricky Fung
*/
@Service
public class QRCodeService {
private static final String CHARSET = "UTF-8";
public File encode(String contents, int width, int height, File qrFile) {
//生成条形码时的一些配置
Map hints = new HashMap<>();
// 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 内容所使用字符集编码
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
BitMatrix bitMatrix;
try {
OutputStream out = new FileOutputStream(qrFile);
// 生成二维码
bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return qrFile;
}
public File encodeWithLogo(File qrFile, File logoFile, File newQrFile) {
OutputStream os = null ;
try {
Image image2 = ImageIO.read(qrFile) ;
int width = image2.getWidth(null) ;
int height = image2.getHeight(null) ;
BufferedImage bufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) ;
//BufferedImage bufferImage =ImageIO.read(image) ;
Graphics2D g2 = bufferImage.createGraphics();
g2.drawImage(image2, 0, 0, width, height, null) ;
int matrixWidth = bufferImage.getWidth();
int matrixHeigh = bufferImage.getHeight();
//读取Logo图片
BufferedImage logo= ImageIO.read(logoFile);
//开始绘制图片
g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);//绘制
BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);// 设置笔画对象
//指定弧度的圆角矩形
RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
g2.setColor(Color.white);
g2.draw(round);// 绘制圆弧矩形
//设置logo 有一道灰色边框
BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);// 设置笔画对象
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
g2.setColor(new Color(128,128,128));
g2.draw(round2);// 绘制圆弧矩形
g2.dispose();
bufferImage.flush() ;
os = new FileOutputStream(newQrFile) ;
JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os) ;
en.encode(bufferImage) ;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return newQrFile ;
}
/**
* ZXing解码
* @param qrFile
* @return
*/
public String decode(File qrFile) {
BufferedImage image = null;
Result result = null;
try {
image = ImageIO.read(qrFile);
if (image == null) {
System.out.println("the decode image may be not exit.");
}
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return result.getText() ;
}
}
2. QRCodeController
package apple.springmvc.zxing.controller;
import apple.springmvc.zxing.model.User;
import apple.springmvc.zxing.service.QRCodeService;
import apple.springmvc.zxing.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
/**
* @author Ricky Fung
*/
@Controller
@RequestMapping("/qr")
public class QRCodeController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String uploadPath = "/images" ;
private int width = 300;
private int height = 300;
@Autowired
private UserService userService;
@Autowired
private QRCodeService qrCodeService;
@RequestMapping(value = "/encode/{userId}", method = RequestMethod.GET)
public ModelAndView genQR(@PathVariable Long userId, HttpServletRequest request){
User user = userService.getUser(userId);
String realUploadPath = request.getServletContext().getRealPath(uploadPath);
logger.info("realUploadPath:{}", realUploadPath);
File uploadDir = new File(realUploadPath);
if(!uploadDir.exists()) {
uploadDir.mkdirs();
}
String imageName = String.format("%s_qr.png", userId);
File qrFile = new File(uploadDir, imageName);
qrCodeService.encode(user.toString(), width, height, qrFile);
logger.info("生成的二维码文件:{}", qrFile.getAbsolutePath());
File logoFile = new File(uploadDir, "logo.png");
imageName = String.format("%s_qr_logo.png", userId);
File logoQrFile = new File(uploadDir, imageName);
qrCodeService.encodeWithLogo(qrFile, logoFile, logoQrFile);
logger.info("生成的带logo二维码文件:{}", logoQrFile.getAbsolutePath());
ModelAndView mv = new ModelAndView("show_qr");
mv.addObject("userId", userId);
mv.addObject("qrImage", uploadPath+"/"+qrFile.getName());
mv.addObject("logoQRImage", uploadPath+"/"+logoQrFile.getName());
return mv;
}
@RequestMapping(value = "/decode/{userId}", method = RequestMethod.GET)
public ModelAndView decodeQR(@PathVariable Long userId, HttpServletRequest request){
User user = userService.getUser(userId);
String realUploadPath = request.getServletContext().getRealPath(uploadPath) ;
File uploadDir = new File(realUploadPath);
String imageName = String.format("%s_qr.png", userId);
File qrFile = new File(uploadDir, imageName);
String result = qrCodeService.decode(qrFile);
ModelAndView mv = new ModelAndView("decode_qr") ;
mv.addObject("result", result);
return mv;
}
}
3. spring-mvc.xml
4. jsp页面
4.1 show_qr.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
二维码与带Logo的二维码
4.2 decode_qr.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
二维码解码结果
${result}
源码
下载链接:https://github.com/TiFG/springmvc-tutorials/tree/master/springmvc-zxing-demo