gistfile1.txt pom支持: com.google.zxing core 3.2.0 com.google.zxing javase 3.2.0 工具类支持:package com.example.demo.dao.qrcode;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.Mult
pom支持:com.google.zxing core3.2.0 工具类支持: 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 com.google.zxing javase3.2.0 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 (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 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); } } 前端显示: 首页 二维码图片1:
二维码图片2:
下载二维码图片3:
下载 }