二维码工具类,提供多种生成二维码、解析二维码的方法,包括中间logo的二维码等方法。

源码如下:(点击下载 - QrcodeUtils.javaMatrixToImageWriterEx.javaMatrixToLogoImageConfig.javacommons-io-2.4.jarcommons-lang-2.6.jarslf4j-api-1.7.12.jarjavase-3.1.0.jarcore-3.1.0.jar 、FolderUtils.java)

QrcodeUtils.java 源码:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.imageio.ImageIO;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
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 com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; /**
* 二维码工具类
*
*/
public class QrcodeUtils { private static final transient Logger LOGGER = LoggerFactory.getLogger(QrcodeUtils.class); private static transient String DEFAULT_FORMAT = "jpg";
private static transient int DEFAULT_WIDTH = 200;
private static transient int DEFAULT_HEIGHT = 200; static {
try {
final String[] foo = new String[] { "240", "240" };
final String format = "jpg";
if (StringUtils.isNotBlank(format)) {
DEFAULT_FORMAT = StringUtils.strip(format).toLowerCase();
} if (ArrayUtils.isNotEmpty(foo) && foo.length == 2) {
Integer tmpWidth = Integer.valueOf(foo[0]);
Integer tmpHeight = Integer.valueOf(foo[1]);
if (tmpWidth > 0 && tmpHeight > 0) {
DEFAULT_WIDTH = tmpWidth;
DEFAULT_HEIGHT = tmpHeight;
} else {
LOGGER.warn("qrcode size must be lager than zero.");
}
}
} catch (Throwable e) {
LOGGER.warn("read default qrcode size config error: ", e);
}
} /**
* 生成二维码(无中间logo)
*
* @param content
* 二维码文本内容
* @param destFile
* 输出文件
*/
public static final void gen(final String content, File destFile) throws Exception {
gen(content, destFile, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destFile
* 目的文件
* @param logoFile
* 中间logo文件
*
*/
public static final void gen(final String content, final File destFile, final File logoFile) throws Exception {
gen(content, destFile, logoFile, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destFile
* 目的文件
* @param logoFile
* 中间logo文件
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content, final File destFile,
final File logoFile, int width, int height) throws Exception {
FolderUtils.mkdirs(destFile.getParent());
OutputStream output = null;
InputStream input = null;
try {
output = new BufferedOutputStream(new FileOutputStream(destFile));
if (logoFile != null && logoFile.exists() && logoFile.isFile()) {
input = new BufferedInputStream(new FileInputStream(logoFile));
}
gen(content, output, input, width, height);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception(e);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
} /**
* 生成二维码(无中间logo)
*
* @param content
* 二维码文本内容
* @param destFile
* 输出文件
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content, File destFile, int width, int height) throws Exception {
FolderUtils.mkdirs(destFile.getParent());
OutputStream output = null;
try {
output = new BufferedOutputStream(new FileOutputStream(destFile));
gen(content, output, width, height);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception(e);
} catch (Exception e) {
throw e;
} finally {
IOUtils.closeQuietly(output);
}
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param output
* 输出流
*/
public static final void gen(final String content, final OutputStream output) throws Exception {
gen(content, output, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param output
* 输出流
* @param logoInput
* 中间logo输入流,为空时中间无logo
*/
public static final void gen(final String content,
final OutputStream output, final InputStream logoInput) throws Exception {
gen(content, output, logoInput, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param output
* 输出流
* @param logoInput
* 中间logo输入流,为空时中间无logo
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content,
final OutputStream output, final InputStream logoInput, int width, int height) throws Exception {
gen(content, output, logoInput, width, height, ErrorCorrectionLevel.M);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param output
* 输出流
* @param logoInput
* 中间logo输入流,为空时中间无logo
* @param width
* 宽度
* @param height
* 高度
* @param errorCorrectionLevel
* 容错级别
*/
public static final void gen(final String content,
final OutputStream output, final InputStream logoInput, int width,
int height, ErrorCorrectionLevel errorCorrectionLevel) throws Exception {
if (StringUtils.isEmpty(content)) {
throw new IllegalArgumentException("qr code content cannot be empty.");
}
if (output == null) {
throw new IllegalArgumentException("qr code output stream cannot be null.");
} final BitMatrix matrix = MatrixToImageWriterEx.createQRCode(content, width, height, errorCorrectionLevel); if (logoInput == null) {
try {
MatrixToImageWriter.writeToStream(matrix, DEFAULT_FORMAT, output);
return;
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e);
}
} final MatrixToLogoImageConfig logoConfig = new MatrixToLogoImageConfig(Color.BLUE, 4); final String destPath = FilenameUtils.normalizeNoEndSeparator(SystemUtils.getJavaIoTmpDir()
+ File.separator + UUID.randomUUID().toString()
+ ".tmp");
InputStream tmpInput = null;
final File destFile = new File(destPath);
try {
MatrixToImageWriterEx.writeToFile(matrix, DEFAULT_FORMAT, destPath, logoInput, logoConfig);
tmpInput = new BufferedInputStream(new FileInputStream(destFile));
IOUtils.copy(tmpInput, output);
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e);
} finally {
IOUtils.closeQuietly(tmpInput);
destFile.delete();
}
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param output
* 输出流
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content, final OutputStream output, int width, int height) throws Exception {
gen(content, output, null, width, height);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destPath
* 输出文件路径
*/
public static final void gen(final String content, final String destPath) throws Exception {
gen(content, destPath, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destPath
* 输出文件路径
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content, final String destPath, int width, int height) throws Exception {
gen(content, new File(destPath), width, height);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destPath
* 目的文件路径
* @param logoPath
* 中间logo文件路径
*/
public static final void gen(final String content, final String destPath, final String logoPath) throws Exception {
gen(content, destPath, logoPath, DEFAULT_WIDTH, DEFAULT_HEIGHT);
} /**
* 生成二维码
*
* @param content
* 二维码文本内容
* @param destPath
* 目的文件路径
* @param logoPath
* 中间logo文件路径
* @param width
* 宽度
* @param height
* 高度
*/
public static final void gen(final String content, final String destPath,
final String logoPath, int width, int height) throws Exception {
File foo = new File(destPath);
File bar = new File(logoPath);
gen(content, foo, bar, width, height);
} /**
* 解析二维码
*
* @param input
* 二维码输入流
*/
public static final String parse(InputStream input) throws Exception {
Reader reader = null;
BufferedImage image;
try {
image = ImageIO.read(input);
if (image == null) {
throw new Exception("cannot read image from inputstream.");
}
final LuminanceSource source = new BufferedImageLuminanceSource(image);
final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
final Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
// 解码设置编码方式为:utf-8,
reader = new MultiFormatReader();
return reader.decode(bitmap, hints).getText();
} catch (IOException e) {
e.printStackTrace();
throw new Exception("parse QR code error: ", e);
} catch (ReaderException e) {
e.printStackTrace();
throw new Exception("parse QR code error: ", e);
}
} /**
* 解析二维码
*
* @param url
* 二维码url
*/
public static final String parse(URL url) throws Exception {
InputStream in = null;
try {
in = url.openStream();
return parse(in);
} catch (IOException e) {
e.printStackTrace();
throw new Exception("parse QR code error: ", e);
} finally {
IOUtils.closeQuietly(in);
}
} /**
* 解析二维码
*
* @param file
* 二维码图片文件
*/
public static final String parse(File file) throws Exception {
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
return parse(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception("parse QR code error: ", e);
} finally {
IOUtils.closeQuietly(in);
}
} /**
* 解析二维码
*
* @param filePath
* 二维码图片文件路径
*/
public static final String parse(String filePath) throws Exception {
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(filePath));
return parse(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception("parse QR code error: ", e);
} finally {
IOUtils.closeQuietly(in);
}
}
}

MatrixToImageWriterEx.java 源码:

import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;
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.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; class MatrixToImageWriterEx { private static final MatrixToLogoImageConfig DEFAULT_CONFIG = new MatrixToLogoImageConfig(); /**
* 根据内容生成二维码数据
*
* @param content
* 二维码文字内容[为了信息安全性,一般都要先进行数据加密]
* @param width
* 二维码照片宽度
* @param height
* 二维码照片高度
* @param errorCorrectionLevel
* 纠错等级
* @return a {@link com.google.zxing.common.BitMatrix} object.
* @since 0.0.7
*/
public static BitMatrix createQRCode(String content, int width, int height,
ErrorCorrectionLevel errorCorrectionLevel) {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 设置字符编码
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
BitMatrix matrix = null;
try {
matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
} catch (WriterException e) {
e.printStackTrace();
}
return matrix;
} /**
* 根据内容生成二维码数据
*
* @param content
* 二维码文字内容[为了信息安全性,一般都要先进行数据加密]
* @param width
* 二维码照片宽度
* @param height
* 二维码照片高度
* @return a {@link com.google.zxing.common.BitMatrix} object.
* @since 0.0.7
*/
public static BitMatrix createQRCode(String content, int width, int height) {
return createQRCode(content, width, height, ErrorCorrectionLevel.H);
} /**
* 写入二维码、以及将照片logo写入二维码中
*
* @param matrix
* 要写入的二维码
* @param format
* 二维码照片格式
* @param imagePath
* 二维码照片保存路径
* @param logoPath
* logo路径
* @throws java.io.IOException
* if any.
* @since 0.0.7
*/
public static void writeToFile(BitMatrix matrix, String format,
String imagePath, String logoPath) throws IOException {
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(logoPath));
writeToFile(matrix, format, imagePath, input);
} catch (IOException e) {
throw e;
} finally {
IOUtils.closeQuietly(input);
} } /**
* <p>
* writeToFile.
* </p>
*
* @param matrix
* a {@link com.google.zxing.common.BitMatrix} object.
* @param format
* a {@link java.lang.String} object.
* @param imagePath
* a {@link java.lang.String} object.
* @param logoInputStream
* a {@link java.io.InputStream} object.
* @throws java.io.IOException
* if any.
* @since 0.0.7
*/
public static void writeToFile(BitMatrix matrix, String format,
String imagePath, InputStream logoInputStream) throws IOException {
MatrixToImageWriter.writeToPath(matrix, format, new File(imagePath).toPath(), new MatrixToImageConfig());
// 添加logo图片, 此处一定需要重新进行读取,而不能直接使用二维码的BufferedImage 对象
BufferedImage img = ImageIO.read(new File(imagePath));
MatrixToImageWriterEx.overlapImage(img, format, imagePath, logoInputStream, DEFAULT_CONFIG);
} /**
* 写入二维码、以及将照片logo写入二维码中
*
* @param matrix
* 要写入的二维码
* @param format
* 二维码照片格式
* @param imagePath
* 二维码照片保存路径
* @param logoPath
* logo路径
* @param logoConfig
* logo配置对象
* @throws java.io.IOException
* if any.
* @since 0.0.7
*/
public static void writeToFile(BitMatrix matrix, String format, String imagePath, InputStream logoPath,
MatrixToLogoImageConfig logoConfig) throws IOException {
MatrixToImageWriter.writeToPath(matrix, format, new File(imagePath).toPath(), new MatrixToImageConfig());
// 添加logo图片, 此处一定需要重新进行读取,而不能直接使用二维码的BufferedImage 对象
BufferedImage img = ImageIO.read(new File(imagePath));
MatrixToImageWriterEx.overlapImage(img, format, imagePath, logoPath, logoConfig);
} /**
* 将照片logo添加到二维码中间
*
* @param image
* 生成的二维码照片对象
* @param imagePath
* 照片保存路径
* @param imagePath
* 照片保存路径
* @param imagePath
* 照片保存路径
* @param imagePath
* 照片保存路径
* @param imagePath
* 照片保存路径
* @param imagePath
* 照片保存路径
* @param logoInputStream
* logo输入流
* @param formate
* 照片格式
* @param logoConfig
* a {@link cn.yicha.commons.qrcode.MatrixToLogoImageConfig}
* object.
* @since 0.0.7
*/
public static void overlapImage(BufferedImage image, String formate,
String imagePath, InputStream logoInputStream,
MatrixToLogoImageConfig logoConfig) {
try {
BufferedImage logo = ImageIO.read(logoInputStream);
Graphics2D g = image.createGraphics();
// 考虑到logo照片贴到二维码中,建议大小不要超过二维码的1/5;
int width = image.getWidth() / logoConfig.getLogoPart();
int height = image.getHeight() / logoConfig.getLogoPart();
// logo起始位置,此目的是为logo居中显示
int x = (image.getWidth() - width) / 2;
int y = (image.getHeight() - height) / 2;
// 绘制图
g.drawImage(logo, x, y, width, height, null); // 给logo画边框
// 构造一个具有指定线条宽度以及 cap 和 join 风格的默认值的实心 BasicStroke
g.setStroke(new BasicStroke(logoConfig.getBorder()));
g.setColor(logoConfig.getBorderColor());
g.drawRect(x, y, width, height); g.dispose();
// 写入logo照片到二维码
ImageIO.write(image, formate, new File(imagePath));
} catch (Exception e) {
e.printStackTrace();
}
} }

MatrixToLogoImageConfig.java 源码:

import java.awt.Color;

class MatrixToLogoImageConfig {
// logo默认边框颜色
/** Constant <code>DEFAULT_BORDERCOLOR</code> */
public static final Color DEFAULT_BORDERCOLOR = Color.RED;
// logo默认边框宽度
/** Constant <code>DEFAULT_BORDER=2</code> */
public static final int DEFAULT_BORDER = 2;
// logo大小默认为照片的1/5
/** Constant <code>DEFAULT_LOGOPART=5</code> */
public static final int DEFAULT_LOGOPART = 5; private final int border = DEFAULT_BORDER;
private final Color borderColor;
private final int logoPart; /**
* Creates a default config with on color {@link #BLACK} and off color
* {@link #WHITE}, generating normal black-on-white barcodes.
*
* @since 0.0.7
*/
public MatrixToLogoImageConfig() {
this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
} /**
* <p>
* Constructor for MatrixToLogoImageConfig.
* </p>
*
* @param borderColor
* a {@link java.awt.Color} object.
* @param logoPart
* a int.
* @since 0.0.7
*/
public MatrixToLogoImageConfig(Color borderColor, int logoPart) {
this.borderColor = borderColor;
this.logoPart = logoPart;
} /**
* <p>
* Getter for the field <code>borderColor</code>.
* </p>
*
* @return a {@link java.awt.Color} object.
* @since 0.0.7
*/
public Color getBorderColor() {
return borderColor;
} /**
* <p>
* Getter for the field <code>border</code>.
* </p>
*
* @return a int.
* @since 0.0.7
*/
public int getBorder() {
return border;
} /**
* <p>
* Getter for the field <code>logoPart</code>.
* </p>
*
* @return a int.
* @since 0.0.7
*/
public int getLogoPart() {
return logoPart;
}
}

转自:小周的博客

二维码工具类 - QrcodeUtils.java的更多相关文章

  1. java二维码工具类,中间带LOGO的,很强大

    jar包下载maven 配置: Xml代码 收藏代码 <dependency> <groupId>com.google.zxing</groupId> <ar ...

  2. Java使用Zxing生成、解析二维码工具类

    Zxing是Google提供的关于条码(一维码.二维码)的解析工具,提供了二维码的生成与解析的方法. 1.二维码的生成 (1).将Zxing-core.jar 包加入到classpath下. (2). ...

  3. java生成二维码工具类

    package com.runtime.extend.utils.CodeCreate; import com.google.zxing.*;import com.google.zxing.commo ...

  4. java 生成微信的二维码 工具类

    package com.app.wii.util; import java.io.File;import java.io.FileInputStream;import java.io.FileOutp ...

  5. iOS开发——生成二维码——工具类

    啥也不说,直接上源码,拷过去就能用.生成二维码的工具类使用方法在ProduceQRCode.h里有示例说明 分别将下面的ProduceQRCode.h和ProduceQRCode.m对应的代码考到自己 ...

  6. iOS开发——扫描二维码——工具类

    (代码已测试好,空闲时间更新……)

  7. java 生成二维码工具

    二维码生成 Gitee:https://gitee.com/search?utf8=%E2%9C%93&search=qrext4j&group_id=&project_id= ...

  8. 你不可错过的二维码生成与解析-java后台与前端js都有

    1.二维码分类   二维条码也有许多不同的码制,就码制的编码原理而言,通常分为三种类型. 线性堆叠式二维码 编码原理: 建立在一维条码基础之上,按需要堆积成两行或多行. 图示: 矩阵式二维码 最常用编 ...

  9. Android二维码工具zxing使用

    二维码在我们生活中随处可见.在我眼里简直能够用"泛滥"来形容啦.那怎样在我们Android项目中扫描识别二维码或生成二维码图片呢? 我们通常使用的开源框架是zxing.在githu ...

随机推荐

  1. MySQL中表格各页面的注意和操作项

  2. hdu 2426 Interesting Housing Problem 最大权匹配KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426 For any school, it is hard to find a feasible ac ...

  3. Load hlsl

    这个函数和sample差不多 不过没有samplestate和filter http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb5096 ...

  4. jQuery新的事件绑定机制on()

    浏览jQuery的deprecated列表,发现live()和die()在里面了,赶紧看了一下,发现从jQuery1.7开始,jQuery引入了全新的事件绑定机制,on()和off()两个函数统一处理 ...

  5. HDOJ 1709 The Balance(母函数)

    The Balance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. Unity动态加载和内存管理(三合一)

    原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Re ...

  7. WIN7设置wifi热点的方法

    1.以管理员身份运行命令提示符:快捷键win+R→输入cmd→回车2.启用并设定虚拟WiFi网卡:运行命令:netsh wlan set hostednetwork mode=allow ssid=m ...

  8. Grid行编辑插件

    //操作列不显示应该就是autoLoad的问题.         Ext.onReady(function () {             Ext.BLANK_IMAGE_URL = "E ...

  9. NSOJ 鬼泣

    今天组队赛的一道最短路的题,给你一个矩阵,矩阵上有L,R,G,A,分别表示当你到达这个点的时候你要向左,向右,向前,向后走,如果要向别的方向走需要花费1点的魔力,正常情况下走需要花费1点的时间.问花费 ...

  10. iOS模型以及使用

    个人习惯,也可以不这样写 创建模型基类: #import <Foundation/Foundation.h> @interface WJBaseModel : NSObject //将字典 ...