Java实现二维码生成的几个方法

Java实现二维码生成的几个方法

版权声明:本文为博主原创文章,转载请注明原处。 https://blog.csdn.net/u014266877/article/details/53665729

 

1、支持QRcode、ZXing 二维码生成、解析;

2、QRCode 方式生成二维码支持添加图片,如下:

 

 

 
  1. package common;

  2.  
  3. import java.awt.Color;

  4. import java.awt.Graphics2D;

  5. import java.awt.Image;

  6. import java.awt.image.BufferedImage;

  7. import java.io.File;

  8. import java.io.IOException;

  9. import java.util.HashMap;

  10. import java.util.Map;

  11.  
  12. import javax.imageio.ImageIO;

  13.  
  14. import jp.sourceforge.qrcode.QRCodeDecoder;

  15. import jp.sourceforge.qrcode.exception.DecodingFailedException;

  16.  
  17. import com.google.zxing.BarcodeFormat;

  18. import com.google.zxing.Binarizer;

  19. import com.google.zxing.BinaryBitmap;

  20. import com.google.zxing.EncodeHintType;

  21. import com.google.zxing.LuminanceSource;

  22. import com.google.zxing.MultiFormatReader;

  23. import com.google.zxing.MultiFormatWriter;

  24. import com.google.zxing.NotFoundException;

  25. import com.google.zxing.WriterException;

  26. import com.google.zxing.common.BitMatrix;

  27. import com.google.zxing.common.HybridBinarizer;

  28. import com.swetake.util.Qrcode;

  29.  
  30. /**

  31. * 二维码生成工具类

  32. * @author Cloud

  33. * @data 2016-12-15

  34. * QRCode

  35. */

  36.  
  37. public class QRCodeUtil {

  38.  
  39. //二维码颜色

  40. private static final int BLACK = 0xFF000000;

  41. //二维码颜色

  42. private static final int WHITE = 0xFFFFFFFF;

  43.  
  44. /**

  45. * <span style="font-size:18px;font-weight:blod;">ZXing 方式生成二维码</span>

  46. * @param text <a href="javascript:void();">二维码内容</a>

  47. * @param width 二维码宽

  48. * @param height 二维码高

  49. * @param outPutPath 二维码生成保存路径

  50. * @param imageType 二维码生成格式

  51. */

  52. public static void zxingCodeCreate(String text, int width, int height, String outPutPath, String imageType){

  53. Map<EncodeHintType, String> his = new HashMap<EncodeHintType, String>();

  54. //设置编码字符集

  55. his.put(EncodeHintType.CHARACTER_SET, "utf-8");

  56. try {

  57. //1、生成二维码

  58. BitMatrix encode = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, his);

  59.  
  60. //2、获取二维码宽高

  61. int codeWidth = encode.getWidth();

  62. int codeHeight = encode.getHeight();

  63.  
  64. //3、将二维码放入缓冲流

  65. BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);

  66. for (int i = 0; i < codeWidth; i++) {

  67. for (int j = 0; j < codeHeight; j++) {

  68. //4、循环将二维码内容定入图片

  69. image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);

  70. }

  71. }

  72. File outPutImage = new File(outPutPath);

  73. //如果图片不存在创建图片

  74. if(!outPutImage.exists())

  75. outPutImage.createNewFile();

  76. //5、将二维码写入图片

  77. ImageIO.write(image, imageType, outPutImage);

  78. } catch (WriterException e) {

  79. e.printStackTrace();

  80. System.out.println("二维码生成失败");

  81. } catch (IOException e) {

  82. e.printStackTrace();

  83. System.out.println("生成二维码图片失败");

  84. }

  85. }

  86.  
  87. /**

  88. * <span style="font-size:18px;font-weight:blod;">二维码解析</span>

  89. * @param analyzePath 二维码路径

  90. * @return

  91. * @throws IOException

  92. */

  93. @SuppressWarnings({ "rawtypes", "unchecked" })

  94. public static Object zxingCodeAnalyze(String analyzePath) throws Exception{

  95. MultiFormatReader formatReader = new MultiFormatReader();

  96. Object result = null;

  97. try {

  98. File file = new File(analyzePath);

  99. if (!file.exists())

  100. {

  101. return "二维码不存在";

  102. }

  103. BufferedImage image = ImageIO.read(file);

  104. LuminanceSource source = new LuminanceSourceUtil(image);

  105. Binarizer binarizer = new HybridBinarizer(source);

  106. BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

  107. Map hints = new HashMap();

  108. hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

  109. result = formatReader.decode(binaryBitmap, hints);

  110. } catch (NotFoundException e) {

  111. e.printStackTrace();

  112. }

  113. return result;

  114. }

  115.  
  116. /**

  117. * <span style="font-size:18px;font-weight:blod;">QRCode 方式生成二维码</span>

  118. * @param content 二维码内容

  119. * @param imgPath 二维码生成路径

  120. * @param version 二维码版本

  121. * @param isFlag 是否生成Logo图片 为NULL不生成

  122. */

  123. public static void QRCodeCreate(String content, String imgPath, int version, String logoPath){

  124. try {

  125. Qrcode qrcodeHandler = new Qrcode();

  126. //设置二维码排错率,可选L(7%) M(15%) Q(25%) H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小

  127. qrcodeHandler.setQrcodeErrorCorrect('M');

  128. //N代表数字,A代表字符a-Z,B代表其他字符

  129. qrcodeHandler.setQrcodeEncodeMode('B');

  130. //版本1为21*21矩阵,版本每增1,二维码的两个边长都增4;所以版本7为45*45的矩阵;最高版本为是40,是177*177的矩阵

  131. qrcodeHandler.setQrcodeVersion(version);

  132. //根据版本计算尺寸

  133. int imgSize = 67 + 12 * (version - 1) ;

  134. byte[] contentBytes = content.getBytes("gb2312");

  135. BufferedImage bufImg = new BufferedImage(imgSize , imgSize ,BufferedImage.TYPE_INT_RGB);

  136. Graphics2D gs = bufImg.createGraphics();

  137. gs.setBackground(Color.WHITE);

  138. gs.clearRect(0, 0, imgSize , imgSize);

  139. // 设定图像颜色 > BLACK

  140. gs.setColor(Color.BLACK);

  141. // 设置偏移量 不设置可能导致解析出错

  142. int pixoff = 2;

  143. // 输出内容 > 二维码

  144. if (contentBytes.length > 0 && contentBytes.length < 130) {

  145. boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);

  146. for (int i = 0; i < codeOut.length; i++) {

  147. for (int j = 0; j < codeOut.length; j++) {

  148. if (codeOut[j][i]) {

  149. gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);

  150. }

  151. }

  152. }

  153. } else {

  154. System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,130 ]. ");

  155. }

  156. /* 判断是否需要添加logo图片 */

  157. if(logoPath != null){

  158. File icon = new File(logoPath);

  159. if(icon.exists()){

  160. int width_4 = imgSize / 4;

  161. int width_8 = width_4 / 2;

  162. int height_4 = imgSize / 4;

  163. int height_8 = height_4 / 2;

  164. Image img = ImageIO.read(icon);

  165. gs.drawImage(img, width_4 + width_8, height_4 + height_8,width_4,height_4, null);

  166. gs.dispose();

  167. bufImg.flush();

  168. }else{

  169. System.out.println("Error: login图片不存在!");

  170. }

  171.  
  172. }

  173.  
  174.  
  175. gs.dispose();

  176. bufImg.flush();

  177. //创建二维码文件

  178. File imgFile = new File(imgPath);

  179. if(!imgFile.exists())

  180. imgFile.createNewFile();

  181. //根据生成图片获取图片

  182. String imgType = imgPath.substring(imgPath.lastIndexOf(".") + 1, imgPath.length());

  183. // 生成二维码QRCode图片

  184. ImageIO.write(bufImg, imgType, imgFile);

  185. } catch (Exception e) {

  186. e.printStackTrace();

  187. }

  188. }

  189.  
  190. /**

  191. * <span style="font-size:18px;font-weight:blod;">QRCode二维码解析</span>

  192. * @param codePath 二维码路径

  193. * @return 解析结果

  194. */

  195. public static String QRCodeAnalyze(String codePath) {

  196. File imageFile = new File(codePath);

  197. BufferedImage bufImg = null;

  198. String decodedData = null;

  199. try {

  200. if(!imageFile.exists())

  201. return "二维码不存在";

  202. bufImg = ImageIO.read(imageFile);

  203.  
  204. QRCodeDecoder decoder = new QRCodeDecoder();

  205. decodedData = new String(decoder.decode(new ImageUtil(bufImg)), "gb2312");

  206. } catch (IOException e) {

  207. System.out.println("Error: " + e.getMessage());

  208. e.printStackTrace();

  209. } catch (DecodingFailedException dfe) {

  210. System.out.println("Error: " + dfe.getMessage());

  211. dfe.printStackTrace();

  212. }

  213. return decodedData;

  214. }

  215.  
  216. }

  217.  
  218.  
  219. 3、最后贴测试代码:

  220.  
  221. package test;

  222.  
  223. import java.awt.image.BufferedImage;

  224. import java.io.InputStream;

  225. import java.net.URL;

  226.  
  227. import javax.imageio.ImageIO;

  228.  
  229. import common.ImageUtil;

  230. import common.QRCodeUtil;

  231.  
  232. import jp.sourceforge.qrcode.QRCodeDecoder;

  233.  
  234. /**

  235. * 二维码生成测试类

  236. * @author Cloud

  237. * @data 2016-11-21

  238. * QRCodeTest

  239. */

  240.  
  241. public class QRCodeTest {

  242.  
  243. public static void main(String[] args) throws Exception {

  244. /**

  245. * QRcode 二维码生成测试

  246. * QRCodeUtil.QRCodeCreate("http://blog.csdn.net/u014266877", "E://qrcode.jpg", 15, "E://icon.png");

  247. */

  248. /**

  249. * QRcode 二维码解析测试

  250. * String qrcodeAnalyze = QRCodeUtil.QRCodeAnalyze("E://qrcode.jpg");

  251. */

  252. /**

  253. * ZXingCode 二维码生成测试

  254. * QRCodeUtil.zxingCodeCreate("http://blog.csdn.net/u014266877", 300, 300, "E://zxingcode.jpg", "jpg");

  255. */

  256. /**

  257. * ZxingCode 二维码解析

  258. * String zxingAnalyze = QRCodeUtil.zxingCodeAnalyze("E://zxingcode.jpg").toString();

  259. */

  260. System.out.println("success");

  261. }

  262. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值