您的位置:首页 > 编程语言 > Java开发

JAVA ZXING生成二维码、条形码

2017-03-29 00:00 585 查看
最近研究zxing生成二维码、条形码,简单写个栗子。为什么不用前端qrcode.js呢,因为它生产的二维码浏览器兼容性不好,不兼容IE7/8。

显示效果,中间logo是百度随便找的。



前端index.jsp

<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2017/3/28 0028
Time: 17:29
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title></title>
</head>
<body>
<img alt="二维码" src="code"/>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<servlet>
<servlet-name>code</servlet-name>
<servlet-class>CodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>code</servlet-name>
<url-pattern>/code</url-pattern>
</servlet-mapping>
</web-app>

条形码、二维码参数实体对象

import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
* Created by Administrator on 2017/3/29 0029.
*/
public class CodeParams {
private String text;                //内容
private String qrcodeFormat = "png"; //保存格式
private String qrCodeUrl;          //网络路径
private String filePath;           //生成物理路径
private String fileName;           //生成图片名称(包含后缀名)
private String logoPath;           //logo图片
private Integer width = 300;           //宽度
private Integer height = 300;          //高度
private Integer onColor = 0xFF000000;  //前景色
private Integer offColor = 0xFFFFFFFF; //背景色
private Integer margin = 1;            //白边大小,取值范围0~4
//二维码容错率 L = ~7% /M = ~15% /Q = ~25% /H = ~30% 容错率越高,二维码的有效像素点就越多
private ErrorCorrectionLevel level = ErrorCorrectionLevel.L;

public String getQrcodeFormat() {
return qrcodeFormat;
}

public void setQrcodeFormat(String qrcodeFormat) {
this.qrcodeFormat = qrcodeFormat;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public String getQrCodeUrl() {
return qrCodeUrl;
}

public void setQrCodeUrl(String qrCodeUrl) {
this.qrCodeUrl = qrCodeUrl;
}

public String getFilePath() {
return filePath;
}

public void setFilePath(String filePath) {
this.filePath = filePath;
}

public String getFileName() {
return fileName;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

public String getLogoPath() {
return logoPath;
}

public void setLogoPath(String logoPath) {
this.logoPath = logoPath;
}

public Integer getWidth() {
return width;
}

public void setWidth(Integer width) {
this.width = width;
}

public Integer getHeight() {
return height;
}

public void setHeight(Integer height) {
this.height = height;
}

public Integer getOnColor() {
return onColor;
}

public void setOnColor(Integer onColor) {
this.onColor = onColor;
}

public Integer getOffColor() {
return offColor;
}

public void setOffColor(Integer offColor) {
this.offColor = offColor;
}

public Integer getMargin() {
return margin;
}

public void setMargin(Integer margin) {
this.margin = margin;
}

public ErrorCorrectionLevel getLevel() {
return level;
}

public void setLevel(ErrorCorrectionLevel level) {
this.level = level;
}
}

servlet

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Created by Administrator on 2017/3/28 0028.
*/
public class CodeServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String type = req.getParameter("type");
//解决中文乱码问题
String contents = new String(req.getParameter("content").getBytes("iso-8859-1"), "utf-8");

if(StringUtils.isNotBlank(contents)){
resp.setCharacterEncoding("utf-8");
ServletOutputStream out = resp.getOutputStream();
CodeParams codeParams = new CodeParams();
codeParams.setText(contents);
codeParams.setMargin(3);
//二维码
if("qr".equals(type)){
ZxingQrcode.createQrcodeToStream(codeParams, out);
// 条形码
} else if("bar".equals(type) ){
codeParams.setHeight(100);
ZxingBarCode.createBarCode(codeParams, out);
String rootPath = "F:\\my-workspace\\zxing\\src\\main\\web\\img";
String barpath = rootPath + "\\bar.png";
//生成条形码图片
ZxingBarCode.createBarCodeImg(codeParams,barpath);
//解析条形码图片
ZxingBarCode.decodeBar(barpath);
}
out.flush();
out.close();
}
}
}

生成二维码

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
* Created by Administrator on 2017/3/28 0028.
*/
public class ZxingQrcode {
/**
* 生成二维码图片输出流
* @param out 图片流
* @return
*/
public static void createQrcodeToStream(CodeParams codeParams,OutputStream out){

try {
// 设置二维码的格式参数
Map<EncodeHintType, Object> hints = getDecodeHintType(codeParams);
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeParams.getText(), BarcodeFormat.QR_CODE, codeParams.getWidth(), codeParams.getHeight(), hints);

//设置前景色、背景色
MatrixToImageConfig config = new MatrixToImageConfig(codeParams.getOnColor(), codeParams.getOffColor());
MatrixToImageWriter.writeToStream(bitMatrix, codeParams.getQrcodeFormat(), out, config);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 生成二维码图片文件,带logo
* @param qrPath 图片文件路径
* @return
*/
public static String createQrcodeImgFile(CodeParams codeParams, String qrPath, String logoPath){

try {
Map<EncodeHintType, Object> hints = getDecodeHintType(codeParams);
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeParams.getText(), BarcodeFormat.QR_CODE, codeParams.getWidth(), codeParams.getHeight(), hints);

BufferedImage image = new BufferedImage( codeParams.getWidth(), codeParams.getHeight(), BufferedImage.TYPE_INT_RGB);
File qrcodeFile = new File(qrPath);
if(!qrcodeFile.exists()){
qrcodeFile.createNewFile();
}
ImageIO.write(image, codeParams.getQrcodeFormat(), qrcodeFile);
//设置前景色、背景色
//生成的二维码图片默认背景为白色,前景为黑色,但是在加入logo图像后会导致logo也变为黑白色,至于是什么原因还没有仔细去读它的源码
//所以这里对其第一个参数黑色将ZXing默认的前景色0xFF000000稍微改了一下0xFF000001,最终效果也是白色背景黑色前景的二维码,且logo颜色保持原有不变
codeParams.setOnColor(0xFF000001);
MatrixToImageConfig config = new MatrixToImageConfig(codeParams.getOnColor(), codeParams.getOffColor());
MatrixToImageWriter.writeToFile(bitMatrix, codeParams.getQrcodeFormat(), qrcodeFile,config);
if (logoPath != null){
addLogo_QRCode(qrcodeFile,logoPath);
}
qrPath = qrcodeFile.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
return qrPath;
}
/**
* 设置二维码的格式参数
*
* @return
*/
public static Map<EncodeHintType, Object> getDecodeHintType(CodeParams codeParams)
{
// 用于设置QR二维码参数
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
hints.put(EncodeHintType.ERROR_CORRECTION, codeParams.getLevel());
hints.put(EncodeHintType.MARGIN, codeParams.getMargin());
// 设置编码方式
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
return hints;
}
/**
* 生成带logo的二维码
*/
public static void addLogo_QRCode(File qrcodeFile, String logoPicPath)
{
try
{
File logoPic = new File(logoPicPath);
if (!logoPic.exists() || !logoPic.isFile())
{
System.out.print("logo file not find !");
return ;
}

//读取二维码图片,并构建绘图对象
BufferedImage image = ImageIO.read(qrcodeFile);
Graphics2D g = image.createGraphics();

//读取Logo图片
BufferedImage logo = ImageIO.read(logoPic);
//设置logo的大小,本人设置为二维码图片的1/6,因为过大会盖掉二维码
int widthLogo = logo.getWidth(null)>image.getWidth()*1/6?(image.getWidth()*1/6):logo.getWidth(null);
int heightLogo = logo.getHeight(null)>image.getHeight()*1/6?(image.getHeight()*1/6):logo.getHeight(null);
// 计算图片放置位置,/logo放在中心
int x = (image.getWidth() - widthLogo) / 2;
int y = (image.getHeight() - heightLogo) / 2;
//开始绘制图片
g.drawImage(logo, x, y, widthLogo, heightLogo, null);
//            g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
//            g.setStroke(new BasicStroke(0));
//            g.drawRect(x, y, widthLogo, heightLogo);

g.dispose();
logo.flush();
image.flush();

ImageIO.write(image, "png",qrcodeFile);
}
catch (Exception e)
{
e.printStackTrace();
}
}

/**
* 解析二维码
*/
public static void decode(String codeImgPath){
File file = new File(codeImgPath);
if(!file.exists()){
return;
}

BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
//复杂模式,开启PURE_BARCODE模式,带图片LOGO的解码方案,否则会出现NotFoundException
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
Result result = null;
try {
result = new MultiFormatReader().decode(bitmap, hints);
} catch (NotFoundException e) {
e.printStackTrace();
}
System.out.println(result.toString());
}

}

生成条形码

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 javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
* Created by Administrator on 2017/3/29 0029.
*/
public class ZxingBarCode {
/**
* 生成条形码输出流
* @param out
*/
public static void createBarCode(CodeParams codeParams,OutputStream out){
try {
Map<EncodeHintType, Object> hints = getDecodeHintType(codeParams);
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeParams.getText(), BarcodeFormat.CODE_128, codeParams.getWidth(), codeParams.getHeight(),hints);
MatrixToImageWriter.writeToStream(bitMatrix, codeParams.getQrcodeFormat(), out);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成条形码图片
*/
public static void createBarCodeImg(CodeParams codeParams, String barPath){
try {

Map<EncodeHintType, Object> hints = getDecodeHintType(codeParams);
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeParams.getText(), BarcodeFormat.CODE_128, codeParams.getWidth(), codeParams.getHeight(), hints);
File file = new File(barPath);
if (!file.exists()){
file.createNewFile();
}
BufferedImage image = new BufferedImage( codeParams.getWidth(), codeParams.getHeight(), BufferedImage.TYPE_INT_RGB);
ImageIO.write(image, codeParams.getQrcodeFormat(), file);
MatrixToImageWriter.writeToFile(bitMatrix, codeParams.getQrcodeFormat(), file);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 针对条形码进行解析
*
* @param imgPath
* @return
*/
public static String decodeBar(String imgPath) {
BufferedImage image = null;
Result result = null;
try {
image = ImageIO.read(new File(imgPath));
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));

result = new MultiFormatReader().decode(bitmap, null);
System.out.println(result.getText());
return result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* 设置二维码的格式参数
*
* @return
*/
public static Map<EncodeHintType, Object> getDecodeHintType(CodeParams codeParams)
{
// 用于设置QR二维码参数
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
hints.put(EncodeHintType.ERROR_CORRECTION, codeParams.getLevel());
hints.put(EncodeHintType.MARGIN, codeParams.getMargin());
// 设置编码方式
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
return hints;
}
}

关于zxing应用更详细的博客地址

提高zxing生成二维码的容错率及zxing生成二维码的边框设置:http://www.cnblogs.com/androidsj/p/4414488.html

zxing 生成二维码,可设置logo、二维码颜色、白边大小

http://blog.csdn.net/rongku/article/details/51872156
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: