1. /**
  2. * 二维码 工具
  3. *
  4. * @author Rubekid
  5. *
  6. */
  7. public class QRcodeUtils {
  8.  
  9. /**
  10. * 默认version
  11. */
  12. public static final int DEFAULT_VERSION = 9;
  13.  
  14. /**
  15. * 图片类型 png (默认) 比较小
  16. */
  17. public static final String IMAGE_TYPE_PNG = "png";
  18.  
  19. /**
  20. * 图片类型 jpg
  21. */
  22. public static final String IMAGE_TYPE_JPEG = "jpg";
  23.  
  24. /**
  25. * 容错率等级 L
  26. */
  27. public static final char CORRECT_L = 'L';
  28.  
  29. /**
  30. * 容错率等级 M
  31. */
  32. public static final char CORRECT_M = 'M';
  33.  
  34. /**
  35. * 容错率等级 Q
  36. */
  37. public static final char CORRECT_Q = 'Q';
  38.  
  39. /**
  40. * 容错率等级 H
  41. */
  42. public static final char CORRECT_H = 'H';
  43.  
  44. /**
  45. * 旁白占用比率
  46. */
  47. public static final double PADDING_RATIO = 0.02;
  48.  
  49. /**
  50. * 生成二维码
  51. *
  52. * @param content
  53. * 要生成的内容
  54. * @param size
  55. * 要生成的尺寸
  56. * @param versoin
  57. * 二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
  58. * @param ecc
  59. * 二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%)
  60. * @return
  61. * @throws Exception
  62. */
  63. public static BufferedImage encode(String content, int size, int version, char ecc) throws Exception {
  64. BufferedImage image = null;
  65. Qrcode qrcode = new Qrcode();
  66. // 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
  67. qrcode.setQrcodeErrorCorrect(ecc);
  68. qrcode.setQrcodeEncodeMode('B');
  69. // 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
  70. qrcode.setQrcodeVersion(version);
  71. // 获得内容的字节数组,设置编码格式
  72. byte[] contentBytes = content.getBytes("utf-8");
  73.  
  74. double ratio = 3;// 默认放大三倍
  75. int qrcodeSize = 21 + 4 * (version - 1);
  76. if (size > 0) {
  77. ratio = (double) size / qrcodeSize;
  78. }
  79. int intRatio = (int) Math.ceil(ratio);
  80.  
  81. // 旁白
  82. int padding = (int) Math.ceil(qrcodeSize * intRatio * PADDING_RATIO);
  83. if (padding < 5) {
  84. padding = 5;
  85. }
  86. // 图片尺寸
  87. int imageSize = qrcodeSize * intRatio + padding * 2;
  88.  
  89. // 图片边长 调整(10的倍数)
  90. if (intRatio > ratio) {
  91. int newSize = (int) Math.ceil(ratio * imageSize / intRatio);
  92. int r = newSize % 10;
  93. newSize += 10 - r;
  94. int newImageSize = (int) Math.floor(intRatio * newSize / ratio);
  95. padding += (newImageSize - imageSize) / 2;
  96. imageSize = newImageSize;
  97. } else {
  98. int r = imageSize % 10;
  99. int d = 10 - r;
  100. padding += d / 2;
  101. imageSize += d;
  102. }
  103.  
  104. image = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_RGB);
  105. Graphics2D gs = image.createGraphics();
  106. // 设置背景颜色
  107. gs.setBackground(Color.WHITE);
  108. gs.clearRect(0, 0, imageSize, imageSize);
  109.  
  110. // 设定图像颜色 BLACK
  111. gs.setColor(Color.BLACK);
  112.  
  113. // 输出内容 二维码
  114. if (contentBytes.length > 0 && contentBytes.length < 800) {
  115. boolean[][] codeOut = qrcode.calQrcode(contentBytes);
  116. for (int i = 0; i < codeOut.length; i++) {
  117. for (int j = 0; j < codeOut.length; j++) {
  118. if (codeOut[j][i]) {
  119. gs.fillRect(j * intRatio + padding, i * intRatio + padding, intRatio, intRatio);
  120. }
  121. }
  122. }
  123. } else {
  124. throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
  125. }
  126. gs.dispose();
  127. image.flush();
  128.  
  129. if (intRatio > ratio) {
  130. image = resize(image, (int) Math.ceil(ratio * imageSize / intRatio));
  131. }
  132. return image;
  133. }
  134.  
  135. /**
  136. * 生成二维码
  137. *
  138. * @param content
  139. * @param size
  140. * @return
  141. * @throws Exception
  142. */
  143. public static BufferedImage encode(String content, int size) throws Exception {
  144. return encode(content, size, DEFAULT_VERSION, CORRECT_Q);
  145. }
  146.  
  147. /**
  148. * 生成二维码
  149. *
  150. * @param content
  151. * @param size
  152. * @param version
  153. * @return
  154. */
  155. public static BufferedImage encode(String content, int size, int version) throws Exception {
  156. return encode(content, size, version, CORRECT_Q);
  157. }
  158.  
  159. /**
  160. * 生成二维码
  161. *
  162. * @param content
  163. * @param size
  164. * @param ecc
  165. * @return
  166. */
  167. public static BufferedImage encode(String content, int size, char ecc) throws Exception {
  168. return encode(content, size, DEFAULT_VERSION, ecc);
  169. }
  170.  
  171. /**
  172. * 生成二维码
  173. *
  174. * @param content
  175. * @return
  176. */
  177. public static BufferedImage encode(String content) throws Exception {
  178. return encode(content, 0, DEFAULT_VERSION, CORRECT_Q);
  179. }
  180.  
  181. /**
  182. * 解析二维码
  183. *
  184. * @throws UnsupportedEncodingException
  185. * @throws DecodingFailedException
  186. */
  187. public static String decode(BufferedImage bufferedImage) throws DecodingFailedException,
  188. UnsupportedEncodingException {
  189. QRCodeDecoder decoder = new QRCodeDecoder();
  190. return new String(decoder.decode(new MyQRCodeImage(bufferedImage)), "utf-8");
  191. }
  192.  
  193. /**
  194. * 下载二维码
  195. *
  196. * @param response
  197. * @param filename
  198. * @param content
  199. * @param size
  200. * @param imageType
  201. * @throws Exception`
  202. */
  203. public static void download(HttpServletResponse response, String filename, String content, int size,
  204. String imageType, String logoPath) throws Exception {
  205. if (size > 2000) {
  206. size = 2000;
  207. }
  208. BufferedImage image = QRcodeUtils.encode(content, size);
  209. if(logoPath !=null){
  210. markLogo(image, logoPath);
  211. }
  212. // 替换占位符
  213. filename = filename.replace("{size}", String.valueOf(image.getWidth()));
  214. InputStream inputStream = toInputStream(image, imageType);
  215. int length = inputStream.available();
  216.  
  217. // 设置response
  218. response.setContentType("application/x-msdownload");
  219. response.setContentLength(length);
  220. response.setHeader("Content-Disposition", "attachment;filename="
  221. + new String(filename.getBytes("gbk"), "iso-8859-1"));
  222.  
  223. // 输出流
  224. byte[] bytes = new byte[1024];
  225. OutputStream outputStream = response.getOutputStream();
  226. while (inputStream.read(bytes) != -1) {
  227. outputStream.write(bytes);
  228. }
  229. outputStream.flush();
  230. }
  231.  
  232. /**
  233. * 下载二维码
  234. * @param response
  235. * @param filename
  236. * @param content
  237. * @param size
  238. * @param imageType
  239. * @throws Exception
  240. */
  241. public static void download(HttpServletResponse response, String filename, String content, int size,
  242. String imageType) throws Exception {
  243. download(response, filename, content, size, imageType, null);
  244. }
  245.  
  246. /**
  247. * 下载二维码
  248. *
  249. * @param response
  250. * @param filename
  251. * @param content
  252. * @param size
  253. * @throws Exception
  254. */
  255. public static void download(HttpServletResponse response, String filename, String content, int size)
  256. throws Exception {
  257. download(response, filename, content, size, IMAGE_TYPE_PNG);
  258. }
  259.  
  260. /**
  261. * 生成二维码文件
  262. * @param destFile
  263. * @param content
  264. * @param size
  265. * @param logoPath
  266. * @throws Exception
  267. */
  268. public static void createQrcodeFile(File destFile, String content, int size, String logoPath) throws Exception{
  269. if(!destFile.exists() || !destFile.isFile()){
  270. destFile.createNewFile();
  271. }
  272. OutputStream outputStream = new FileOutputStream(destFile);
  273. BufferedImage image = QRcodeUtils.encode(content, size);
  274. if(logoPath !=null){
  275. markLogo(image, logoPath);
  276. }
  277. InputStream inputStream = toInputStream(image, QRcodeUtils.IMAGE_TYPE_PNG);
  278. // 输出流
  279. byte[] bytes = new byte[1024];
  280. while (inputStream.read(bytes) != -1) {
  281. outputStream.write(bytes);
  282. }
  283. inputStream.close();
  284. outputStream.close();
  285. }
  286.  
  287. /**
  288. * 生成二维码文件
  289. * @param destFile
  290. * @param content
  291. * @param size
  292. * @throws Exception
  293. */
  294. public static void createQrcodeFile(File destFile, String content, int size) throws Exception{
  295. createQrcodeFile(destFile, content, size, null);
  296. }
  297.  
  298. /**
  299. * logo水印
  300. * @param qrcode
  301. * @param logoPath
  302. * @throws IOException
  303. */
  304. public static void markLogo(BufferedImage qrcode, String logoPath) throws IOException{
  305. File logoFile = new File(logoPath);
  306. if(logoFile.exists()){
  307. Graphics2D gs = qrcode.createGraphics();
  308. int width = qrcode.getWidth();
  309. int height = qrcode.getHeight();
  310. Image logo = ImageIO.read(logoFile);
  311.  
  312. int scale = 6; //显示为图片的 1/n;
  313.  
  314. //logo显示大小
  315. int lw = width / scale;
  316. int lh = height / scale;
  317. int wx = (width - lw) /2;
  318. int wy = (height -lh) / 2;
  319. gs.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
  320. gs.drawImage(logo, wx, wy, lw, lh, null); // 图片水印文件结束
  321. gs.dispose();
  322. qrcode.flush();
  323. }
  324.  
  325. }
  326.  
  327. /**
  328. * 获取内容二维码图片出流
  329. *
  330. * @param content
  331. * @param size
  332. * @param imageType
  333. * @return
  334. * @throws Exception
  335. * InputStream
  336. */
  337. public static InputStream getQrcodeImageStream(String content, int size, String imageType, String logoPath) throws Exception {
  338. if (size > 2000) {
  339. size = 2000;
  340. }
  341. BufferedImage image = QRcodeUtils.encode(content, size);
  342. if(logoPath!=null){
  343. markLogo(image, logoPath);
  344. }
  345. return toInputStream(image, imageType);
  346. }
  347.  
  348. public static InputStream getQrcodeImageStream(String content, int size, String imageType) throws Exception {
  349. return getQrcodeImageStream(content, size, imageType, null);
  350. }
  351.  
  352. /**
  353. * 转成InputStream
  354. * @param image
  355. * @param imageType
  356. * @return
  357. * @throws IOException
  358. */
  359. private static InputStream toInputStream(BufferedImage image, String imageType) throws IOException{
  360. // BufferedImage 转 InputStream
  361. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  362. ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);
  363.  
  364. // 生成jpg格式
  365. if (IMAGE_TYPE_JPEG.equals(imageType)) {
  366. Iterator<ImageWriter> iterator = ImageIO.getImageWritersByFormatName("jpeg");
  367. ImageWriter imageWriter = iterator.next();
  368. ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
  369. imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
  370. imageWriteParam.setCompressionQuality(1); // 设置质量
  371. imageWriter.setOutput(imageOutput);
  372. IIOImage iioImage = new IIOImage(image, null, null);
  373. imageWriter.write(null, iioImage, imageWriteParam);
  374. imageWriter.dispose();
  375. } else {
  376. ImageIO.write(image, "png", imageOutput);
  377. }
  378. return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
  379. }
  380.  
  381. /**
  382. * 图片缩放
  383. */
  384. private static BufferedImage resize(BufferedImage image, int size) {
  385. int imageSize = (size % 2) > 0 ? (size + 1) : size;
  386.  
  387. BufferedImage bufferedImage = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_RGB);
  388. Graphics2D gs = bufferedImage.createGraphics();
  389. gs.setBackground(Color.WHITE);
  390. gs.clearRect(0, 0, imageSize, imageSize);
  391. gs.setColor(Color.BLACK);
  392. gs.fillRect(0, 0, imageSize, imageSize);
  393. gs.drawImage(image, 0, 0, size, size, null);
  394. gs.dispose();
  395. image.flush();
  396. return bufferedImage;
  397. }
  398.  
  399. }

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. Dapper事务操作

    1.报错信息: 如果分配给命令的连接位于本地挂起事务中,ExecuteNonQuery 要求命令拥有事务.命令的 Transaction 属性尚未初始化. 出现这种原因是在执行Execute语句时,没 ...

  2. centos的常用命令

    公司服务器主要是centos,第一篇就从centos的常用命令开始吧. 转载自:http://www.cnblogs.com/zitsing/archive/2012/05/02/2479009.ht ...

  3. onchar

    void CMfcView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)//Windows响应函数 { // TODO: Add your messag ...

  4. GetTextMetrics

    该函数的参数要求是一个TEXTMETRIC结构体的指针 也就是说我们可以定义一个结构类型的变量 将该变量的地址传递进来 通过该函数就能得到当前字体的信息来填充这个结构体 int CXuexi2View ...

  5. 文成小盆友python-num12 Redis发布与订阅补充,python操作rabbitMQ

    本篇主要内容: redis发布与订阅补充 python操作rabbitMQ 一,redis 发布与订阅补充 如下一个简单的监控模型,通过这个模式所有的收听者都能收听到一份数据. 用代码来实现一个red ...

  6. OSTaskCreateExt() 建立任务

    OSTaskCreateExt()建立任务 NT8U OSTaskCreateExt (void   (*task)(void *pd), void    *pdata, OS_STK *ptos, ...

  7. nginx 中location和root

    nginx 中location和root,你确定真的明白他们关系? 2016-01-17 14:48 3774人阅读 评论(1) 收藏 举报  分类: linux(17)  版权声明:本文为博主原创文 ...

  8. JS对undefined,null,NaN判断

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

  9. 设置 cell点击 背景色

    //设置 cell点击 背景色 cell.selectionStyle = UITableViewCellSelectionStyleDefault; cell.selectedBackgroundV ...

  10. Cracking the coding interview--Q1.5

    原文 Implement a method to perform basic string compression using the counts of repeated characters. F ...