1. 程式人生 > >生成二維碼,返回檔案位元組碼,或將檔案轉成base64返回

生成二維碼,返回檔案位元組碼,或將檔案轉成base64返回

    @PostMapping("/admin/get/qrcode")
    public  ResponseEntity<byte[]>  getQrcode(Long id,boolean needlogo) throws IOException, FrameworkException{
     File file = themeService.getQrCode(id,needlogo);
     InputStream qrcode = new FileInputStream(file);
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  byte[] buffer = new byte[1024];
  int len = qrcode.read(buffer);
  while (len >= 0) {
   out.write(buffer, 0, len);
   len = qrcode.read(buffer);
  }
  qrcode.close();
  HttpHeaders headers = new HttpHeaders();
  headers.set(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_JPEG_VALUE);  
  return new ResponseEntity<byte[]>(out.toByteArray(), headers, HttpStatus.OK);
    }

 

 private String imageToBase64(File file) throws IOException { 
     InputStream in = new FileInputStream(file);
  byte[] data =  new byte[in.available()];
  in.read(data);
  in.close();
     BASE64Encoder encoder = new BASE64Encoder();
     return encoder.encode(data);
    }

以下為封裝的二維碼圖片生成工具類

引入pom

 <!-- qrCode 二維碼 -->
  <dependency>
   <groupId>com.google.zxing</groupId>
   <artifactId>core</artifactId>
   <version>3.3.3</version>
  </dependency>
  <dependency>
   <groupId>com.google.zxing</groupId>
   <artifactId>javase</artifactId>
   <version>3.3.3</version>
  </dependency>
 

 

 

 

package com.chehaha.theme;

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import com.chehaha.common.util.file.FileUtil;
import com.chehaha.common.util.string.StringUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeUtil {
 private static final String CHARSET = "UTF-8";
 private static final String FORMAT_NAME = "JPG";
 // 二維碼尺寸
 private static final int QRCODE_SIZE = 200;
 // LOGO寬度
 private static final int WIDTH = 60;
 // LOGO高度
 private static final int HEIGHT = 60;

 /**
  * user: Rex date: 2016年12月29日 上午12:31:29
  *
  * @param content
  *            二維碼內容
  * @param logoImgPath
  *            Logo
  * @param needCompress
  *            是否壓縮Logo
  * @return 返回二維碼圖片
  * @throws WriterException
  * @throws IOException
  *             BufferedImage TODO 建立二維碼圖片
  */
 private static BufferedImage createImage(String content, String logoImgPath, boolean needCompress)
   throws WriterException, IOException {
  Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
  hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
  hints.put(EncodeHintType.MARGIN, 1);
  BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
    hints);
  int width = bitMatrix.getWidth();
  int height = bitMatrix.getHeight();
  BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  for (int x = 0; x < width; x++) {
   for (int y = 0; y < height; y++) {
    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
   }
  }
  if (logoImgPath == null || "".equals(logoImgPath)) {
   return image;
  }

  // 插入圖片
  QRCodeUtil.insertImage(image, logoImgPath, needCompress);
  return image;
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:30:09
  *
  * @param source
  *            二維碼圖片
  * @param logoImgPath
  *            Logo
  * @param needCompress
  *            是否壓縮Logo
  * @throws IOException
  *             void TODO 新增Logo
  */
 private static void insertImage(BufferedImage source, String logoImgPath, boolean needCompress) throws IOException {
  File file = new File(logoImgPath);
  if (!file.exists()) {
   return;
  }

  Image src = ImageIO.read(new File(logoImgPath));
  int width = src.getWidth(null);
  int height = src.getHeight(null);
  if (needCompress) { // 壓縮LOGO
   if (width > WIDTH) {
    width = WIDTH;
   }

   if (height > HEIGHT) {
    height = HEIGHT;
   }

   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 = (QRCODE_SIZE - width) / 2;
  int y = (QRCODE_SIZE - height) / 2;
  graph.drawImage(src, x, y, width, height, null);
  Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
  graph.setStroke(new BasicStroke(3f));
  graph.draw(shape);
  graph.dispose();
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:32:32
  *
  * @param content
  *            二維碼內容
  * @param logoImgPath
  *            Logo
  * @param destPath
  *            二維碼輸出路徑
  * @param needCompress
  *            是否壓縮Logo
  * @throws IOException
  * @throws WriterException
  * @throws Exception
  *             void TODO 生成帶Logo的二維碼
  */
 public static void encode(String content, String logoImgPath, String destPath, boolean needCompress)
   throws IOException, WriterException {
  BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress);
  mkdirs(destPath);
  ImageIO.write(image, FORMAT_NAME, new File(destPath));
 }
 
 public static void mkdirs(String dir) {
  if (StringUtil.isEmpty(dir)) {
   return;
  }

  File file = new File(dir);
  if (file.isDirectory()) {
   return;
  } else {
   file.mkdirs();
  }
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:35:44
  *
  * @param content
  *            二維碼內容
  * @param destPath
  *            二維碼輸出路徑
  * @throws WriterException
  * @throws IOException
  * @throws Exception
  *             void TODO 生成不帶Logo的二維碼
  */
 public static void encode(String content, String destPath) throws IOException, WriterException {
  QRCodeUtil.encode(content, null, destPath, false);
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:36:58
  *
  * @param content
  *            二維碼內容
  * @param logoImgPath
  *            Logo
  * @param output
  *            輸出流
  * @param needCompress
  *            是否壓縮Logo
  * @throws IOException
  * @throws WriterException
  * @throws Exception
  *             void TODO 生成帶Logo的二維碼,並輸出到指定的輸出流
  */
 public static void encode(String content, String logoImgPath, OutputStream output, boolean needCompress)
   throws WriterException, IOException {
  BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress);
  ImageIO.write(image, FORMAT_NAME, output);
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:38:02
  *
  * @param content
  *            二維碼內容
  * @param output
  *            輸出流
  * @throws IOException
  * @throws WriterException
  * @throws Exception
  *             void TODO 生成不帶Logo的二維碼,並輸出到指定的輸出流
  */
 public static void encode(String content, OutputStream output) throws WriterException, IOException {
  QRCodeUtil.encode(content, null, output, false);
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:39:10
  *
  * @param file
  *            二維碼
  * @return 返回解析得到的二維碼內容
  * @throws IOException
  * @throws NotFoundException
  * @throws Exception
  *             String TODO 二維碼解析
  */
 public static String decode(File file) throws IOException, NotFoundException {
  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, CHARSET);
  result = new MultiFormatReader().decode(bitmap, hints);
  String resultStr = result.getText();
  return resultStr;
 }

 /**
  * user: Rex date: 2016年12月29日 上午12:39:48
  *
  * @param path
  *            二維碼儲存位置
  * @return 返回解析得到的二維碼內容
  * @throws IOException
  * @throws NotFoundException
  * @throws Exception
  *             String TODO 二維碼解析
  */
 public static String decode(String path) throws NotFoundException, IOException {
  return QRCodeUtil.decode(new File(path));
 }

 public static void main(String[] args) throws Exception {
  String logo = "E:\\work\\web\\img\\logo-o.png";
  String content = "https://clic.chehaha.net/agent/share?inc=95BBE820FE11D34BC5298720930D94F5";
  String file = "C:\\Users\\James.Wong\\Desktop\\my-qrcode.png";
  // OutputStream os = new FileOutputStream(file);
  QRCodeUtil.encode(content, logo, file, true);
 }
}