/**
* 二维码 工具
*
* @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. java8+spring+angularjs 项目应用

    最近有写一个电子订单商务网站,使用JAVA8,SPRING,ANGULARJS对项目使用的技术和大家分享. 第一次写博客,哪有不对需要改正的请联系改正. 因为是项目是我给别人做的无法提供源码见谅,我尽 ...

  2. php mkdir 创建多级目录实例代码

    先介绍一下 mkdir() 这个函数 mkdir($path,0777,true); 第一个参数:必须,代表要创建的多级目录的路径. 第二个参数:设定目录的权限,默认是 0777,意味着最大可能的访问 ...

  3. 利用google浏览器开发者工具调试网页(详)

    前端程序员或者在校大学生正在开发网页,如果想要测试或者通过测试优化网页结构,该怎么办呢?这就需要用到一款工具,chrome浏览器的开发者工具?本文写给尚不熟悉这个开发者工具的同学们或者同行们,话不多说 ...

  4. Properties配置文件

    package file; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; ...

  5. 前端MVC学习笔记(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  6. WPC文件修改还原pin进度

    原文地址:http://wenku.baidu.com/link?url=KZRR6VtW_Yn59iEbrWYz15jOH6hSVgjyow8nvwHfQr3eQgvCcc9IgYCT-fWwVWf ...

  7. Altium Designer中使用差分对布线

    Contents Language 在原理图中定义差分对 在PCB中查看和管理差分对 在PCB中定义差分对 适用的设计规则 设置设计规则的辖域 使用差分对向导定义规则 差分对布线 包括管脚交换的FPG ...

  8. c#—— Task.FromResult 的使用

    Task.FromResult用来创建一个带返回值的.已完成的Task. 场景一:以同步的方式实现一个异步接口方法 比如有一个接口包含异步方法. interface IMyInterface { Ta ...

  9. Java---设计模块(工厂方法)

    ★ 场景和问题 Java程序开发讲究面向接口编程,隐藏具体的实现类,可是如何得到接口呢? 工厂类的命名规范:***Factory 单例工厂方法的命名规范:getInstance() 工厂的本质是&qu ...

  10. HDU_1230——火星A+B,加法进制问题

    Problem Description 读入两个不超过25位的火星正整数A和B,计算A+B.需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数.例如:地球上的10进制数2,在火星上 ...