/**
* 二维码 工具
*
* @author Rubekid
*
*/
public class QRcodeUtils { /**
* 默认version
*/
public static final int DEFAULT_VERSION = 9; /**
* 图片类型 png (默认) 比较小
*/
public static final String IMAGE_TYPE_PNG = "png"; /**
* 图片类型 jpg
*/
public static final String IMAGE_TYPE_JPEG = "jpg"; /**
* 容错率等级 L
*/
public static final char CORRECT_L = 'L'; /**
* 容错率等级 M
*/
public static final char CORRECT_M = 'M'; /**
* 容错率等级 Q
*/
public static final char CORRECT_Q = 'Q'; /**
* 容错率等级 H
*/
public static final char CORRECT_H = 'H'; /**
* 旁白占用比率
*/
public static final double PADDING_RATIO = 0.02; /**
* 生成二维码
*
* @param content
* 要生成的内容
* @param size
* 要生成的尺寸
* @param versoin
* 二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
* @param ecc
* 二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%)
* @return
* @throws Exception
*/
public static BufferedImage encode(String content, int size, int version, char ecc) throws Exception {
BufferedImage image = null;
Qrcode qrcode = new Qrcode();
// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
qrcode.setQrcodeErrorCorrect(ecc);
qrcode.setQrcodeEncodeMode('B');
// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
qrcode.setQrcodeVersion(version);
// 获得内容的字节数组,设置编码格式
byte[] contentBytes = content.getBytes("utf-8"); double ratio = 3;// 默认放大三倍
int qrcodeSize = 21 + 4 * (version - 1);
if (size > 0) {
ratio = (double) size / qrcodeSize;
}
int intRatio = (int) Math.ceil(ratio); // 旁白
int padding = (int) Math.ceil(qrcodeSize * intRatio * PADDING_RATIO);
if (padding < 5) {
padding = 5;
}
// 图片尺寸
int imageSize = qrcodeSize * intRatio + padding * 2; // 图片边长 调整(10的倍数)
if (intRatio > ratio) {
int newSize = (int) Math.ceil(ratio * imageSize / intRatio);
int r = newSize % 10;
newSize += 10 - r;
int newImageSize = (int) Math.floor(intRatio * newSize / ratio);
padding += (newImageSize - imageSize) / 2;
imageSize = newImageSize;
} else {
int r = imageSize % 10;
int d = 10 - r;
padding += d / 2;
imageSize += d;
} image = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = image.createGraphics();
// 设置背景颜色
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, imageSize, imageSize); // 设定图像颜色 BLACK
gs.setColor(Color.BLACK); // 输出内容 二维码
if (contentBytes.length > 0 && contentBytes.length < 800) {
boolean[][] codeOut = qrcode.calQrcode(contentBytes);
for (int i = 0; i < codeOut.length; i++) {
for (int j = 0; j < codeOut.length; j++) {
if (codeOut[j][i]) {
gs.fillRect(j * intRatio + padding, i * intRatio + padding, intRatio, intRatio);
}
}
}
} else {
throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
}
gs.dispose();
image.flush(); if (intRatio > ratio) {
image = resize(image, (int) Math.ceil(ratio * imageSize / intRatio));
}
return image;
} /**
* 生成二维码
*
* @param content
* @param size
* @return
* @throws Exception
*/
public static BufferedImage encode(String content, int size) throws Exception {
return encode(content, size, DEFAULT_VERSION, CORRECT_Q);
} /**
* 生成二维码
*
* @param content
* @param size
* @param version
* @return
*/
public static BufferedImage encode(String content, int size, int version) throws Exception {
return encode(content, size, version, CORRECT_Q);
} /**
* 生成二维码
*
* @param content
* @param size
* @param ecc
* @return
*/
public static BufferedImage encode(String content, int size, char ecc) throws Exception {
return encode(content, size, DEFAULT_VERSION, ecc);
} /**
* 生成二维码
*
* @param content
* @return
*/
public static BufferedImage encode(String content) throws Exception {
return encode(content, 0, DEFAULT_VERSION, CORRECT_Q);
} /**
* 解析二维码
*
* @throws UnsupportedEncodingException
* @throws DecodingFailedException
*/
public static String decode(BufferedImage bufferedImage) throws DecodingFailedException,
UnsupportedEncodingException {
QRCodeDecoder decoder = new QRCodeDecoder();
return new String(decoder.decode(new MyQRCodeImage(bufferedImage)), "utf-8");
} /**
* 下载二维码
*
* @param response
* @param filename
* @param content
* @param size
* @param imageType
* @throws Exception`
*/
public static void download(HttpServletResponse response, String filename, String content, int size,
String imageType, String logoPath) throws Exception {
if (size > 2000) {
size = 2000;
}
BufferedImage image = QRcodeUtils.encode(content, size);
if(logoPath !=null){
markLogo(image, logoPath);
}
// 替换占位符
filename = filename.replace("{size}", String.valueOf(image.getWidth()));
InputStream inputStream = toInputStream(image, imageType);
int length = inputStream.available(); // 设置response
response.setContentType("application/x-msdownload");
response.setContentLength(length);
response.setHeader("Content-Disposition", "attachment;filename="
+ new String(filename.getBytes("gbk"), "iso-8859-1")); // 输出流
byte[] bytes = new byte[1024];
OutputStream outputStream = response.getOutputStream();
while (inputStream.read(bytes) != -1) {
outputStream.write(bytes);
}
outputStream.flush();
} /**
* 下载二维码
* @param response
* @param filename
* @param content
* @param size
* @param imageType
* @throws Exception
*/
public static void download(HttpServletResponse response, String filename, String content, int size,
String imageType) throws Exception {
download(response, filename, content, size, imageType, null);
} /**
* 下载二维码
*
* @param response
* @param filename
* @param content
* @param size
* @throws Exception
*/
public static void download(HttpServletResponse response, String filename, String content, int size)
throws Exception {
download(response, filename, content, size, IMAGE_TYPE_PNG);
} /**
* 生成二维码文件
* @param destFile
* @param content
* @param size
* @param logoPath
* @throws Exception
*/
public static void createQrcodeFile(File destFile, String content, int size, String logoPath) throws Exception{
if(!destFile.exists() || !destFile.isFile()){
destFile.createNewFile();
}
OutputStream outputStream = new FileOutputStream(destFile);
BufferedImage image = QRcodeUtils.encode(content, size);
if(logoPath !=null){
markLogo(image, logoPath);
}
InputStream inputStream = toInputStream(image, QRcodeUtils.IMAGE_TYPE_PNG);
// 输出流
byte[] bytes = new byte[1024];
while (inputStream.read(bytes) != -1) {
outputStream.write(bytes);
}
inputStream.close();
outputStream.close();
} /**
* 生成二维码文件
* @param destFile
* @param content
* @param size
* @throws Exception
*/
public static void createQrcodeFile(File destFile, String content, int size) throws Exception{
createQrcodeFile(destFile, content, size, null);
} /**
* logo水印
* @param qrcode
* @param logoPath
* @throws IOException
*/
public static void markLogo(BufferedImage qrcode, String logoPath) throws IOException{
File logoFile = new File(logoPath);
if(logoFile.exists()){
Graphics2D gs = qrcode.createGraphics();
int width = qrcode.getWidth();
int height = qrcode.getHeight();
Image logo = ImageIO.read(logoFile); int scale = 6; //显示为图片的 1/n; //logo显示大小
int lw = width / scale;
int lh = height / scale;
int wx = (width - lw) /2;
int wy = (height -lh) / 2;
gs.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
gs.drawImage(logo, wx, wy, lw, lh, null); // 图片水印文件结束
gs.dispose();
qrcode.flush();
} } /**
* 获取内容二维码图片出流
*
* @param content
* @param size
* @param imageType
* @return
* @throws Exception
* InputStream
*/
public static InputStream getQrcodeImageStream(String content, int size, String imageType, String logoPath) throws Exception {
if (size > 2000) {
size = 2000;
}
BufferedImage image = QRcodeUtils.encode(content, size);
if(logoPath!=null){
markLogo(image, logoPath);
}
return toInputStream(image, imageType);
} public static InputStream getQrcodeImageStream(String content, int size, String imageType) throws Exception {
return getQrcodeImageStream(content, size, imageType, null);
} /**
* 转成InputStream
* @param image
* @param imageType
* @return
* @throws IOException
*/
private static InputStream toInputStream(BufferedImage image, String imageType) throws IOException{
// BufferedImage 转 InputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream); // 生成jpg格式
if (IMAGE_TYPE_JPEG.equals(imageType)) {
Iterator<ImageWriter> iterator = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter imageWriter = iterator.next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(1); // 设置质量
imageWriter.setOutput(imageOutput);
IIOImage iioImage = new IIOImage(image, null, null);
imageWriter.write(null, iioImage, imageWriteParam);
imageWriter.dispose();
} else {
ImageIO.write(image, "png", imageOutput);
}
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
} /**
* 图片缩放
*/
private static BufferedImage resize(BufferedImage image, int size) {
int imageSize = (size % 2) > 0 ? (size + 1) : size; BufferedImage bufferedImage = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, imageSize, imageSize);
gs.setColor(Color.BLACK);
gs.fillRect(0, 0, imageSize, imageSize);
gs.drawImage(image, 0, 0, size, size, null);
gs.dispose();
image.flush();
return bufferedImage;
} }

Java 二维码生成工具类的更多相关文章

  1. 二维码生成工具类java版

    注意:这里我不提供所需jar包的路径,我会把所有引用的jar包显示出来,大家自行Google package com.net.util; import java.awt.BasicStroke; im ...

  2. java二维码生成工具

    import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.ut ...

  3. Java二维码生成与解码工具Zxing使用

    Zxing是Google研发的一款非常好用的开放源代码的二维码生成工具,目前源码托管在github上,源码地址: https://github.com/zxing/zxing 可以看到Zxing库有很 ...

  4. java二维码生成-谷歌(Google.zxing)开源二维码生成学习及实例

    java二维码生成-谷歌(Google.zxing)开源二维码生成的实例及介绍   我们使用比特矩阵(位矩阵)的QR码编码在缓冲图片上画出二维码 实例有以下一个传入参数 OutputStream ou ...

  5. Java二维码生成与解码

      基于google zxing 的Java二维码生成与解码   一.添加Maven依赖(解码时需要上传二维码图片,所以需要依赖文件上传包) <!-- google二维码工具 --> &l ...

  6. java 二维码生成

    直接上代码: 二维码生成核心类: package com.bbkj.wechat.tool; import java.awt.image.BufferedImage; import java.io.F ...

  7. 谷歌zxing 二维码生成工具

    一.加入maven依赖 <!-- 谷歌zxing 二维码 --> <dependency> <groupId>com.google.zxing</groupI ...

  8. java 二维码生成(可带图片)springboot版

    本文(2019年6月29日 飞快的蜗牛博客) 有时候,男人和女人是两个完全不同的世界,男人的玩笑和女人的玩笑也完全是两码事,爱的人完全不了解你,你也不要指望一个女人了解你,所以男的不是要求别人怎么样, ...

  9. [转]java二维码生成与解析代码实现

    转载地址:点击打开链接 二维码,是一种采用黑白相间的平面几何图形通过相应的编码算法来记录文字.图片.网址等信息的条码图片.如下图 二维码的特点: 1.  高密度编码,信息容量大 可容纳多达1850个大 ...

随机推荐

  1. JavaScript 客户端JavaScript之样式表操作(DOM API 提供模块之一)

    层叠样式 表和动态HTML   层叠样式表(CSS)是指定HTML文档或XML文档的表现的标准.     使用CSS和Javascript,可以创建出各种视觉效果,这些效果可以统称为动态HTML(DH ...

  2. STL 之 vector 用法

    一.头文件 #include<vector> 二.常用方法: // 在这个向量的尾部插入x的考贝,平均时间为常数,最坏时间为O(n): 1: void push_back(const T& ...

  3. windows核心编程-信号量(semaphore)

    线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了互斥器线程同步-----windows核心编程-互斥器(Mutexes),这章我来介绍一下信号量(semaphore)线程同步. ...

  4. Bash shell 笔记总结(一) 转自http://www.bubuko.com/infodetail-509992.html,谢谢原作者

    本文是上课笔记总结,涉及细节知识点会在以后文章说明! bash脚本编程: 脚本程序:解释器解释执行: shell: 交互式接口:编程环境: shell: 能够提供一些内部命令,并且能通过PATH环境变 ...

  5. NET Core & VS Code 之路(2) Web API

    NET Core & VS Code 之路(2) Web API 开发Core项目的条件 Visual Studio 2015 Update 3 .NET Core 1.0.0 - VS 20 ...

  6. IDEA启动自动进入最后一个项目

    每次打开IDEA的时候总会加载上级最后打开的工程,可能这个工程并不是我需要的,我就得重新去打开我需要的工程,感觉这一点非常鸡肋. 使用如下方法可以在启动的时候,选择启动哪个工程,而不是直接进入. Fi ...

  7. C#数据类型汇总

    通用类型系统 C#中,变量是值还是引用仅取决于数据类型 所有的数据类型都是对象.因为它们具有自己ide方法和属性 int int_value = 101; //调用*int_value*的比较方法与整 ...

  8. 使用john破解ubuntu(linux)9.10密码

    Title:使用john破解ubuntu(linux)9.10密码 --2011-11-23 15:00 ubuntu 9.10的账户密码加密方式改用sha512了,默认的john是破不了的,还好官方 ...

  9. Ubuntu12.04 下安装Chrome浏览器

    第一步 下载. 32位:https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb 64位:https://dl. ...

  10. Javascript Array Distinct (array.reduce实现)

    javascript 没有原生的Distinct功能 . (至少现在还没有)但我们可以通过简单的script 自己实现 . Distinct就是把数组中重复出现2次或以上的值给删除掉,确保数组内每个值 ...