pom 支持:
- <!-- 二维码支持包 start-->
- <dependency>
- <groupId>com.google.zxing</groupId>
- <artifactId>core</artifactId>
- <version>3.2.0</version>
- </dependency>
- <dependency>
- <groupId>com.google.zxing</groupId>
- <artifactId>javase</artifactId>
- <version>3.2.0</version>
- </dependency>
- <!-- 二维码支持包 end-->
工具类支持:
- package com.example.demo.dao.qrcode;
- import com.google.zxing.BarcodeFormat;
- import com.google.zxing.EncodeHintType;
- import com.google.zxing.MultiFormatWriter;
- import com.google.zxing.WriterException;
- import com.google.zxing.client.j2se.MatrixToImageWriter;
- import com.google.zxing.common.BitMatrix;
- import com.google.zxing.qrcode.QRCodeWriter;
- import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.http.ResponseEntity;
- import javax.imageio.ImageIO;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.IOException;
- import java.util.Hashtable;
- /**
- * @author jin.tang
- * @Title: springbootdemo
- * @Package com.example.demo.dao.qrcode
- * @Description: java Web 二维码生成器
- * @date 2017/12/25
- */
- @Slf4j
- public class QRCodeUtil {
- /**
- * 方式一: 流的方式直接生成 Web 版本二维码
- * 默认的二维码外观 (可设置高宽)
- * @param url 要生成二维码的路径
- * @param response response 对象
- * @param width 二维码宽度
- * @param height 二维码高度
- * @throws IOException
- */
- public static void getTwoDimension(String url, HttpServletResponse response, int width, int height) throws IOException {
- if (url != null && !"".equals(url)) {
- ServletOutputStream stream = null;
- try {
- stream = response.getOutputStream();
- QRCodeWriter writer = new QRCodeWriter();
- BitMatrix m = writer.encode(url, BarcodeFormat.QR_CODE, height, width);
- MatrixToImageWriter.writeToStream(m, "png", stream);
- } catch (WriterException e) {
- e.printStackTrace();
- log.error("生成二维码失败!");
- } finally {
- if (stream != null) {
- stream.flush();
- stream.close();
- }
- }
- }
- }
- /**
- * 方式二: 返回 ResponseEntity 的方式显示二维码
- * 可设置二维码外观颜色, logo 图片
- * @param url 二维码对于 URL
- * @param width 二维码宽
- * @param height 二维码高
- * @param format 二维码格式
- * @param logPath logo 图片路径
- * @param needLogo 二维码是否需要生成 logo
- * @return
- * @throws WriterException
- * @throws IOException
- */
- // 直接在页面显示
- public static ResponseEntity<byte[]> getResponseEntity(String url, String logPath, boolean needLogo,String format,int width,int height)throws Exception {
- BufferedImage image = QRCodeUtil.createImage(url, logPath,needLogo,width,height);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ImageIO.write(image, format, out);// 将 BufferedImage 转成 out 输出流
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
- return new ResponseEntity<byte[]>(out.toByteArray(),
- headers, HttpStatus.CREATED);
- }
- /**
- * 方式三: 以流的形式直接显示二维码
- * 可设置二维码外观颜色, logo 图片
- */
- public static void showQrcode(String url, String logPath,HttpServletResponse response, boolean needLog,String format,int width,int height)throws Exception {
- BufferedImage image = QRCodeUtil.createImage(url, logPath,needLog,width,height);
- boolean bl = ImageIO.write(image, format, response.getOutputStream());
- System.out.println("boolean is" + bl);
- } /** 方式四: 生成二维码文件存储
- * 可设置二维码外观颜色, logo 图片
- * @param logPath
- * @param destPath 存储路径
- * @param fileName 存储文件名称 (不需要后缀)
- * @param needLog
- * @param format
- * @param width
- * @param height
- * @return
- * @throws Exception
- */
- public static boolean SaveQrCode(String url, String logPath,
- boolean needLog,String format,int width,int height,String destPath, String fileName) throws Exception {
- boolean flag = false;
- BufferedImage image;
- try {
- image = QRCodeUtil.createImage(url, logPath,needLog,width,height);
- File file = new File(destPath);
- // 当文件夹不存在时, mkdirs 会自动创建多层目录, 区别于 mkdir.(mkdir 如果父目录不存在则会抛出异常)
- if (!file.exists() && !file.isDirectory()) {
- file.mkdirs();
- }
- String fileUrl = fileName + "."+format;
- ImageIO.write(image, format, new File(destPath + "/" + fileUrl));
- flag = true;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return flag;
- } /**
- * 生成二维码图片私有方法
- */
- private static BufferedImage createImage (String url, String imgPath,boolean needCompress,
- int width, int height) throws Exception {
- Hashtable hints = new Hashtable();
- // 二维码纠错级别: 由高到低 H,Q,M,L
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
- hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
- // 二维码边界空白大小由大到小 4,3,2,1(默认为 4)
- hints.put(EncodeHintType.MARGIN, 1);
- BitMatrix bitMatrix = new MultiFormatWriter().encode(url,
- BarcodeFormat.QR_CODE, width, height, hints);
- int H = bitMatrix.getHeight();
- int W = bitMatrix.getWidth();
- int L = getFinderPatternWidth(bitMatrix) + 3;
- int[] pixels = new int[W * H];
- // 二维码角颜色, 依次为左上, 左下, 右上
- Color redColor = new Color(182, 0, 5);
- int redColorInt = redColor.getRGB();
- Color greenColor = new Color(0, 124, 54);
- int greenColorInt = greenColor.getRGB();
- Color blueColor = new Color(0, 64, 152);
- int blueColorInt = blueColor.getRGB();
- for (int y = 0; y < H; y++) {
- for (int x = 0; x < W; x++) {
- // 颜色渐变程度, RGB(158,255,158)
- int num1 = (int) (158 - (158.0 - 30.0) / bitMatrix.getHeight()
- * (y + 1));
- int num2 = (int) (255 - (255.0 - 80.0) / bitMatrix.getHeight()
- * (y + 1));
- int num3 = (int) (158 - (158.0 - 130.0) / bitMatrix.getHeight()
- * (y + 1));
- Color color = new Color(num1, num2, num3);
- int colorInt = color.getRGB();
- // 此处可以修改二维码的颜色, 可以分别制定二维码和背景的颜色;
- pixels[y * W + x] = bitMatrix.get(x, y) ? colorInt : 0xffffff;
- }
- }
- BufferedImage image = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
- image.getRaster().setDataElements(0, 0, W, H, pixels);
- if (imgPath == null || "".equals(imgPath)) {
- return image;
- }
- // 插入图片
- QRCodeUtil.insertImage(image, imgPath, needCompress,width,height);
- return image; }
- private static int getFinderPatternWidth(BitMatrix matrix) {
- int W = matrix.getWidth();
- int H = matrix.getHeight();
- int length = 0;
- boolean flag = false;
- for (int y = 0; y < H; y++) {
- for (int x = 0; x < W; x++) {
- if (matrix.get(x, y) == true) {
- flag = true;
- length++;
- } else {
- if (flag != false) {
- return x;
- }
- }
- }
- }
- return length;
- }
- /**
- * 在二维码中插入图片
- */
- private static void insertImage(BufferedImage source, String imgPath,
- boolean needCompress,int wid,int hei) 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 > wid) {
- width = wid;
- }
- if (height > hei) {
- height = hei;
- }
- Image image = src.getScaledInstance(width, height,
- Image.SCALE_SMOOTH);
- BufferedImage tag = new BufferedImage(width, height,
- 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 = (wid - width) / 2;
- int y = (hei - height) / 2;
- /*
- * int x = QRCODE_SIZE - width - 20; int y = QRCODE_SIZE - height - 20;
- */
- graph.drawImage(src, x, y, width, height, null);
- // logo 边框
- /*
- * Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
- * graph.setStroke(new BasicStroke(3f)); graph.draw(shape);
- */
- graph.dispose();
- }
controller 中调用:
package com.example.demo.controller; import com.example.demo.dao.qrcode.QRCodeUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.Web.bind.annotation.RequestMapping; import org.springframework.Web.bind.annotation.RequestMethod; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author jin.tang * @Title: springbootdemo * @Package com.example.demo.controller * @Description: ${todo} * @date 2017/12/25 */ @Slf4j @Controller public class QRCodeController { /** * 获得二维码 * @param request * @param response */ @RequestMapping(value = "phoneversion/getTwoDimension",method={RequestMethod.POST,RequestMethod.GET}) public void getTwoDimensionForIOSs(HttpServletRequest request, HttpServletResponse response){ try { QRCodeUtil.getTwoDimension("https://bbs.hupu.com/bxj", response, 300, 300); } catch (IOException e) { e.printStackTrace(); } } @RequestMapping("/downloadIOSAPPQRCode") public ResponseEntity<byte[]> downloadIOSAPPController(/*@RequestParam(required = true)String type*/) throws Exception{ // InputStream is = this.getClass().getClassLoader().getResourceAsStream("app.properties"); // Properties props = new Properties(); // props.load(is); // String appId = (String)props.get(type); // String url = "" + appId; return QRCodeUtil.getResponseEntity("https://www.zhibo8.cc", "F:\\logo.png",true,"png", 300, 300); } @RequestMapping("/showQrcode") public void showQrcode(HttpServletRequest request, HttpServletResponse response) throws Exception{ QRCodeUtil.showQrcode("https://www.zhibo8.cc", "",response,false,"png", 300, 300); } @RequestMapping("/SaveQrCode") public void SaveQrCode(HttpServletRequest request, HttpServletResponse response) throws Exception{ boolean flag=QRCodeUtil.SaveQrCode("https://www.zhibo8.cc", "",false,"png", 300, 300,"D:\\","qrcode"); log.info("flag=="+flag); } }
前端显示:
<!DOCTYPE HTML> <HTML lang="en"> <head> <meta charset="UTF-8" /> <title> 首页 & lt;/title> </head> <body> <p> 二维码图片 1: </p> <div> <img src="/phoneversion/getTwoDimension" alt="" /> </div> <p> 二维码图片 2: </p> <img src="/downloadIOSAPPQRCode" /> <a href="/downloadIOSAPPQRCode"> 下载 & lt;/a> <p> 二维码图片 3: </p> <img src="/showQrcode" /> <a href="/showQrcode"> 下载 & lt;/a> </body> </HTML> }
来源: http://www.bubuko.com/infodetail-2907145.html