用JAVA自己画一张二维码

我们都知道,最近2年移动支付在中国堪称新四大发明之一。

二维码无处不在,特别是最近的支付宝扫码领红包,微信,qq,到处在发,阿里有点攻占腾讯移动支付市场的势头啊~博主忽然就对二维码是怎么画的有了点好奇,然后自己就整了一下,整体看下来比较简单,好了废话不多说,直接上码~

1,新建一个工程,如下图,命名为QRcode,然后新建package 命名为code

2,新建一个类QRCode,代码如下:

  1 package code; 
  2 
  3 import java.awt.Color; 
  4 import java.awt.Graphics2D; 
  5 import java.awt.image.BufferedImage; 
  6 import java.io.File; 
  7 import java.io.IOException; 
  8 import java.io.InputStream; 
  9 import java.io.OutputStream; 
 10 
 11 import javax.imageio.ImageIO; 
 12 
 13 import jp.sourceforge.qrcode.QRCodeDecoder; 
 14 import jp.sourceforge.qrcode.exception.DecodingFailedException; 
 15 
 16 import com.swetake.util.Qrcode; 
 17 
 18 public class QRCode { 
 19 
 20 /** 
 21 * 生成二维码(QRCode)图片 
 22 * @param content 存储内容 
 23 * @param imgPath 图片路径 
 24 */ 
 25 public void encoderQRCode(String content, String imgPath) { 
 26 this.encoderQRCode(content, imgPath, "png", 10); 
 27 } 
 28 
 29 /** 
 30 * 生成二维码(QRCode)图片 
 31 * @param content 存储内容 
 32 * @param output 输出流 
 33 */ 
 34 public void encoderQRCode(String content, OutputStream output) { 
 35 this.encoderQRCode(content, output, "png", 10); 
 36 } 
 37 
 38 /** 
 39 * 生成二维码(QRCode)图片 
 40 * @param content 存储内容 
 41 * @param imgPath 图片路径 
 42 * @param imgType 图片类型 
 43 */ 
 44 public void encoderQRCode(String content, String imgPath, String imgType) { 
 45 this.encoderQRCode(content, imgPath, imgType, 10); 
 46 } 
 47 
 48 /** 
 49 * 生成二维码(QRCode)图片 
 50 * @param content 存储内容 
 51 * @param output 输出流 
 52 * @param imgType 图片类型 
 53 */ 
 54 public void encoderQRCode(String content, OutputStream output, String imgType) { 
 55 this.encoderQRCode(content, output, imgType, 10); 
 56 } 
 57 
 58 /** 
 59 * 生成二维码(QRCode)图片 
 60 * @param content 存储内容 
 61 * @param imgPath 图片路径 
 62 * @param imgType 图片类型 
 63 * @param size 二维码尺寸 
 64 */ 
 65 public void encoderQRCode(String content, String imgPath, String imgType, int size) { 
 66 try { 
 67 BufferedImage bufImg = this.qRCodeCommon(content, imgType, size); 
 68 
 69 File imgFile = new File(imgPath); 
 70 // 生成二维码QRCode图片 
 71 ImageIO.write(bufImg, imgType, imgFile); 
 72 } catch (Exception e) { 
 73 e.printStackTrace(); 
 74 } 
 75 } 
 76 
 77 /** 
 78 * 生成二维码(QRCode)图片 
 79 * @param content 存储内容 
 80 * @param output 输出流 
 81 * @param imgType 图片类型 
 82 * @param size 二维码尺寸 
 83 */ 
 84 public void encoderQRCode(String content, OutputStream output, String imgType, int size) { 
 85 try { 
 86 BufferedImage bufImg = this.qRCodeCommon(content, imgType, size); 
 87 // 生成二维码QRCode图片 
 88 ImageIO.write(bufImg, imgType, output); 
 89 } catch (Exception e) { 
 90 e.printStackTrace(); 
 91 } 
 92 } 
 93 
 94 /** 
 95 * 生成二维码(QRCode)图片的公共方法 
 96 * @param content 存储内容 
 97 * @param imgType 图片类型 
 98 * @param size 二维码尺寸 
 99 * @return 
100 */ 
101 private BufferedImage qRCodeCommon(String content, String imgType, int size) { 
102 BufferedImage bufImg = null; 
103 try { 
104 Qrcode qrcodeHandler = new Qrcode(); 
105 // 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小 
106 qrcodeHandler.setQrcodeErrorCorrect('M'); 
107 qrcodeHandler.setQrcodeEncodeMode('B'); 
108 // 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大 
109 qrcodeHandler.setQrcodeVersion(size); 
110 // 获得内容的字节数组,设置编码格式 
111 byte[] contentBytes = content.getBytes("utf-8"); 
112 // 图片尺寸 
113 int imgSize = 67 + 12 * (size - 1); 
114 bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB); 
115 Graphics2D gs = bufImg.createGraphics(); 
116 // 设置背景颜色 
117 gs.setBackground(Color.WHITE); 
118 gs.clearRect(0, 0, imgSize, imgSize); 
119 
120 // 设定图像颜色> BLACK 
121 gs.setColor(Color.BLACK); 
122 // 设置偏移量,不设置可能导致解析出错 
123 int pixoff = 2; 
124 // 输出内容> 二维码 
125 if (contentBytes.length > 0 && contentBytes.length < 1600) { 
126 boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes); 
127 for (int i = 0; i < codeOut.length; i++) { 
128 for (int j = 0; j < codeOut.length; j++) { 
129 if (codeOut[j][i]) { 
130 gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3); 
131 } 
132 } 
133 } 
134 } else { 
135 throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800]."); 
136 } 
137 gs.dispose(); 
138 bufImg.flush(); 
139 } catch (Exception e) { 
140 e.printStackTrace(); 
141 } 
142 return bufImg; 
143 } 
144 
145 /** 
146 * 解析二维码(QRCode) 
147 * @param imgPath 图片路径 
148 * @return 
149 */ 
150 public String decoderQRCode(String imgPath) { 
151 // QRCode 二维码图片的文件 
152 File imageFile = new File(imgPath); 
153 BufferedImage bufImg = null; 
154 String content = null; 
155 try { 
156 bufImg = ImageIO.read(imageFile); 
157 QRCodeDecoder decoder = new QRCodeDecoder(); 
158 content = new String(decoder.decode(new TwoDimensionCodeImage(bufImg)), "utf-8"); 
159 } catch (IOException e) { 
160 System.out.println("Error: " + e.getMessage()); 
161 e.printStackTrace(); 
162 } catch (DecodingFailedException dfe) { 
163 System.out.println("Error: " + dfe.getMessage()); 
164 dfe.printStackTrace(); 
165 } 
166 return content; 
167 } 
168 
169 /** 
170 * 解析二维码(QRCode) 
171 * @param input 输入流 
172 * @return 
173 */ 
174 public String decoderQRCode(InputStream input) { 
175 BufferedImage bufImg = null; 
176 String content = null; 
177 try { 
178 bufImg = ImageIO.read(input); 
179 QRCodeDecoder decoder = new QRCodeDecoder(); 
180 content = new String(decoder.decode(new TwoDimensionCodeImage(bufImg)), "utf-8"); 
181 } catch (IOException e) { 
182 System.out.println("Error: " + e.getMessage()); 
183 e.printStackTrace(); 
184 } catch (DecodingFailedException dfe) { 
185 System.out.println("Error: " + dfe.getMessage()); 
186 dfe.printStackTrace(); 
187 } 
188 return content; 
189 } 
190 }

 

 

3,再新建一个图片对象类TwoDimensionCodeImage ,代码如下:

 1 package code;
 2 
 3 import java.awt.image.BufferedImage; 
 4 
 5 import jp.sourceforge.qrcode.data.QRCodeImage; 
 6 
 7 public class TwoDimensionCodeImage implements QRCodeImage { 
 8 
 9 BufferedImage bufImg; 
10 
11 public TwoDimensionCodeImage(BufferedImage bufImg) { 
12 this.bufImg = bufImg; 
13 } 
14 
15 @Override 
16 public int getHeight() { 
17 return bufImg.getHeight(); 
18 } 
19 
20 @Override 
21 public int getPixel(int x, int y) { 
22 return bufImg.getRGB(x, y); 
23 } 
24 
25 @Override 
26 public int getWidth() { 
27 return bufImg.getWidth(); 
28 } 
29 
30 }

 

4,最重要的部分来了,引入QRCode.jar包,如下图,(注,jar包地址就不写了,可自行百度下载~包也不大)

 

5,整个项目调试没有报错,即可。

6,我们来写一段测试代码试试,代码如下:

 1 public static void main(String[] args) { 
 2 String imgPath = "C:\\Users\\JJJ\\Desktop\\11.jpg"; 
 3 String encoderContent = "曾经\r\n 有人说我帅我不承认\r\n 然后他们就打我\r\n 现在\r\n 那些说我帅的人 \r\n都用手机扫到了这张图\r\n 他们会不会又想打我~\r\n →_→ Merry Christmas~JJJ";
 4 QRCode handler = new QRCode(); 
 5 handler.encoderQRCode(encoderContent, imgPath, "png"); 
 6 System.out.println("========encoder success"); 
 7 String decoderContent = handler.decoderQRCode(imgPath); 
 8 System.out.println("解析结果如下:"); 
 9 System.out.println(decoderContent); 
10 System.out.println("========decoder success!!!"); 
11 } 

7,测试结果截图如下:

 

撸完收功~

 

整个还是相对来说很简单的,因为主要的画图部分功能,都是由QRcode.jar包完成的,另外要说明的是,我们的字符串长度是有限制的,目前代码中是10*10的矩阵,如果要显示更多的字符就需要将矩阵调大。最大是44*44貌似,最小是7*7,如果没记错的话~

写在最后

忽然发现我们以后去相亲的话,自己制作一张二维码,写上工作,姓名,年龄,爱好,等等~互相扫一扫,是不是也是很方便啊~还有就是可以自己制作一张二维码发给朋友或者对象,调戏一下,也是不错的~作为一名程序员,是不是可以尽显我们的逼格~不然总以为我们只会修电脑~~

 

posted @ 2017-12-26 11:52  队长给我球。  阅读(1944)  评论(14编辑  收藏  举报