用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,如果没记错的话~
写在最后
忽然发现我们以后去相亲的话,自己制作一张二维码,写上工作,姓名,年龄,爱好,等等~互相扫一扫,是不是也是很方便啊~还有就是可以自己制作一张二维码发给朋友或者对象,调戏一下,也是不错的~作为一名程序员,是不是可以尽显我们的逼格~不然总以为我们只会修电脑~~
give me the ball!