/**
* 二维码 工具
*
* @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. c#geckofx文件流下载

    备注:内容仅提供参考. ⒈添加引用:using Gecko; ⒉然后根据自己的情况在某个方法内添加事件: LauncherDialog.Download += new EventHandler< ...

  2. hadoop实现共同出现的单词(Word co-occurrence)

    共同出现的单词(Word co-occurrence)是指在一个句子中相邻的两个单词.每一个相邻的单词就是一个Co-Occurrence对. Sample Input: a b cc, c d d c ...

  3. 3.2 GUN as汇编(本文内容大部分引用原文,非原创)

    as86汇编仅仅用于编译内核中的boot/bootsect.s引导扇区程序和实模式下的设置程序boot/setup.s.内核中其余所有汇编语言程序(包括C语言产生的汇编程序)均使用gas来编译,并与C ...

  4. Python交互模式下方向键出现乱码

    解决办法如下: 1.安装readline模块 readline库是bash shell用的库,包含许多功能,如命令行自动补全等. ubuntu下安装的命令:   sudo apt-get instal ...

  5. 数值统计 AC 杭电

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. C/C++堆栈指引(转)

    C/C++堆栈指引 Binhua Liu 前言 我们经常会讨论这样的问题:什么时候数据存储在堆栈(Stack)中,什么时候数据存储在堆(Heap)中.我们知道,局部变量是存储在堆栈中的:debug时, ...

  7. CSS3 加载进度样式

    <html> <head> <style type="text/css"> body{ background-color: green; } . ...

  8. HBase笔记--filter的使用

    HBASE过滤器介绍: 所有的过滤器都在服务端生效,叫做谓语下推(predicate push down),这样可以保证被过滤掉的数据不会被传送到客户端. 注意:        基于字符串的比较器,如 ...

  9. JS对undefined,null,NaN判断

    1.判断undefined: <span style="font-size: small;">var tmp = undefined; if (typeof(tmp) ...

  10. UIApplication-备用

    iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...