最近在做生成二维码的功能,就是那种放在网页里头,是一张二维码图片,用户扫一扫就可以在手机上看的。
例如:这种。实现方式有多种,有直接根据流输出的,有直接转成图片的等等。话不多说,直接上代码:
@RequestMapping(value = "matrix")
public void getMatrix(String id, String type,HttpServletRequest request, HttpServletResponse response) {
// 设置响应的类型格式为图片格式
response.setContentType("image/png");
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// String basePath = request.getScheme() + "://" +
// request.getServerName() + ":" + request.getServerPort() +
// request.getContextPath();
// String basePath ="http://172.16.10.31:8082/laozicloudpc/";
String basePath =PropertiesUtil.getProperty("web.host");
String text = basePath, format = "png";
logger.info(basePath);
//看戶型
if("1".equals(type)) {
text = text+ "mobilereality/laozicloud/model/houseModel?id=" + id;
}else if("2".equals(type)) {
text = text+ "mobilereality/laozicloud/model/playModel?id=" + id;
}
System.out.println("text:"+text);
int width = 300, height = 300;
// 二维码的图片格式
Map<EncodeHintType, String> mapEs = new Hashtable<EncodeHintType, String>();
// 内容所使用编码
mapEs.put(EncodeHintType.CHARACTER_SET, "utf-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, mapEs);
MatrixUtils.writeToStream(bitMatrix, format, response.getOutputStream());
} catch (IOException ie) {
ie.printStackTrace();
logger.info("Matrix io exception:" + ie.getMessage());
} catch (Exception e) {
e.printStackTrace();
logger.info("Matrix WriterException:" + e.getMessage());
try {
response.getOutputStream().close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
这里需要在maven仓库中引入包,如下:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
以及工具类MatrixUtils:
package org.mobilereality.laozicloud.utils;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import com.google.zxing.common.BitMatrix;
/**
* Matrix Utils
*
* @author Damon yang
* @version 1.0
*/
public class MatrixUtils {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private MatrixUtils() {
}
/**
* image buffered format
*
* @param matrix
* @return
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
/**
* write an image to file
*
* @param matrix
* @param format
* @param file
* @throws IOException
*/
public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
/**
* write an image to stream
*
* @param matrix
* @param format
* @param stream
* @throws IOException
*/
public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, stream)) {
throw new IOException("Could not write an image of format " + format);
}
}
}
除了以流的方式输出外,工具类还提供了writeToFile,toBufferedImage方法,表示直接可以写成文件。下面再介绍一种返回base64位字符串的方式:
@PostMapping(value = "getMatrix")
public FeedbackVO getMatrix(String modelId,String type,HttpServletRequest request, HttpServletResponse response) {
// 设置响应的类型格式为图片格式
response.setContentType("image/png");
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
String text="";
//看戶型
if("MOBILE_MODEL_SHOW".equals(type)) {
String basePath =PropertiesUtil.getProperty("laozicloud.mobile.host");
text = basePath+ "mobilereality/laozicloud/model/show/"+modelId;
}
System.out.println("text:"+text);
int width = 300, height = 300;
// 二维码的图片格式
Map<EncodeHintType, String> mapEs = new Hashtable<EncodeHintType, String>();
// 内容所使用编码
mapEs.put(EncodeHintType.CHARACTER_SET, "utf-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, mapEs);
ByteArrayOutputStream bao=new ByteArrayOutputStream();
BufferedImage bufferedImage = MatrixUtils.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage,"png",bao);
byte[] matrixB = bao.toByteArray();
String maxtrix = new sun.misc.BASE64Encoder().encode(matrixB);
return FeedbackVO.success("data:image/png;base64,"+maxtrix);
} catch (IOException ie) {
ie.printStackTrace();
// logger.info("Matrix io exception:" + ie.getMessage());
}
catch (Exception e) {
e.printStackTrace();
// logger.info("Matrix WriterException:" + e.getMessage());
try {
response.getOutputStream().close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return FeedbackVO.fail("000010", "生成base64失败");
}
前端就很简单了,直接请求即可。不管返回的是流还是base64位字符串。写法都一样,为:<img src="${ctx}/model/matrix"/>.即可