1.二维码扫描
二维码,是一种采用黑白相间的平面几何图形通过相应的编码算法来记录文字、图片、网址等信息的条码图片。如下图
二维码的特点:
1. 高密度编码,信息容量大
可容纳多达1850个大写字母或2710个数字或1108个字节,或500多个汉字,比普通条码信息容量约高几十倍。
2. 编码范围广
该条码可以把图片、声音、文字、签字、指纹等可以数字化的信息进行编码,用条码表示出来;可以表示多种语言文字;可表示图像数据。
3. 容错能力强,具有纠错功能
这使得二维条码因穿孔、污损等引起局部损坏时,照样可以正确得到识读,损毁面积达50%仍可恢复信息。
4. 译码可靠性高
它比普通条码译码错误率百万分之二要低得多,误码率不超过千万分之一。
5. 可引入加密措施
保密性、防伪性好。
6. 成本低,易制作,持久耐用
正因为以上这些特点,二维码现在越来越流行,应用也是越来越广(详细了解请见百度百科,介绍不是本篇重点),所以掌握如何开发二维码是非常不错的知识储备,因此本篇博文将为大家讲解如何生成、解析二维码。
所需jar包:QRCode.jar
http://download.csdn.net/detail/wangpeng047/4008532
TwoDimensionCode类:二维码操作核心类
1 package qrcode; 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 TwoDimensionCode { 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", 7); 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", 7); 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, 7); 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, 7); 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 < 800) { 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 191 public static void main(String[] args) { 192 String imgPath = "G:/TDDOWNLOAD/Michael_QRCode.png"; 193 String encoderContent = "Hello 大大、小小,welcome to QRCode!" + "\nMyblog [ http://sjsky.iteye.com ]" + "\nEMail [ sjsky007@gmail.com ]"; 194 TwoDimensionCode handler = new TwoDimensionCode(); 195 handler.encoderQRCode(encoderContent, imgPath, "png"); 196 // try { 197 // OutputStream output = new FileOutputStream(imgPath); 198 // handler.encoderQRCode(content, output); 199 // } catch (Exception e) { 200 // e.printStackTrace(); 201 // } 202 System.out.println("========encoder success"); 203 204 205 String decoderContent = handler.decoderQRCode(imgPath); 206 System.out.println("解析结果如下:"); 207 System.out.println(decoderContent); 208 System.out.println("========decoder success!!!"); 209 } 210 }
TwoDimensionCodeImage 类:二维码图片对象
1 package qrcode; 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 }