Java 条形码 二维码 的生成与解析
Barcode简介
Barcode是由一组按一定编码规则排列的条,空符号,用以表示一定的字符,数字及符号组成的,一种机器可读的数据表示方式。
Barcode的形式多种多样,按照它们的外观分类:
Linear barcode(一维码):它的信息存储量小,仅能存储一个代号,使用时通过这个代号调取计算机网络中的数据。
Matrix barcode(二维码)。二维码是近几年发展起来的,它能在有限的空间内存储更多的信息,包括文字、图象、指纹、签名等,并可脱离计算机使用。
你可能认为你对它们都有所了解,因为它们大概都是这个样子的:
但事实上,它们有甚至有可能是这样子的:
我们通常所说的二维码,只是Matrix barcode的一种,叫做QR code。
Barcode种类繁多,有些编码格式并不常用,即使是ZXing也没有做到所有格式的支持,开发者只需了解就好。
其中包括:
一维条码编码格式:
Code39码(标准39码)、Codabar码(库德巴码)、Code25码(标准25码)、ITF25码(交叉25码)、Matrix25码(矩阵25码)、UPC-A码、UPC-E码、
EAN-13码(EAN-13国际商品条码)、EAN-8码(EAN-8国际商品条码)、中国邮政码(矩阵25码的一种变体)、Code-B码、MSI码、Code11码、Code93码、ISBN码、ISSN码、
Code128码(Code128码,包括EAN128码)、Code39EMS(EMS专用的39码)等
二维条码编码格式:
PDF417码、Code49码、Code 16k码、Date Matrix码、MaxiCode码(包括 QR Code码)等。
Code 39、Code 128、EAN、UPC、QR Code是我们生活中能经常见到的几种编码格式,同时ZXing对几种格式都有比较好的支持。
其中,UPC-A是一种国际通用的编码格式,由12个数字构成,EAN-13是在UPC-A基础上的一种扩充(多了一个数字)。快数一数你身边的薯片的编码是不是13位!如果是的话,它最前边的两个数字是不是“69”?
在EAN-13的编码体系中,前三位数字表示商品生产商的国家(并不是商品所属公司的国家),中国的编码是690~699,美国是(000~019、030~039、060~139),日本是(450~459、490~499),and so on。
不同的编码格式通常用在不同的领域,如果你看到了一个Code 39或者Code 128的Barcode,那么这很就可能是一个快递编码,这个时候你就可以去那些提供快递查询的网站查询一下你的快递信息,如果有API提供出来那就更是再好不过了。
至于QR Code,就是我们经常用手机扫一扫的二维码,表示的信息更是多种多样,并不仅仅是一个url那么简单,至于这些信息如何处理,是我们一会儿将要讨论的内容。
一、google的zxing(jar包下载)
1:条形码的生成与解码(生成的条形码不显示 本身的条码含义,即:条码下方没有数字字母等。如有需要,自行拼接)
1 import java.awt.image.BufferedImage; 2 import java.io.File; 3 import java.io.FileOutputStream; 4 5 import javax.imageio.ImageIO; 6 7 import com.google.zxing.BarcodeFormat; 8 import com.google.zxing.BinaryBitmap; 9 import com.google.zxing.LuminanceSource; 10 import com.google.zxing.MultiFormatReader; 11 import com.google.zxing.MultiFormatWriter; 12 import com.google.zxing.Result; 13 import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 14 import com.google.zxing.client.j2se.MatrixToImageWriter; 15 import com.google.zxing.common.BitMatrix; 16 import com.google.zxing.common.HybridBinarizer; 17 18 public class ZxingEAN13Code { 19 /** 20 * 条形码编码 21 * @param contents 22 * @param width 23 * @param height 24 * @param imgPath 25 */ 26 public void encode(String contents, int width, int height, String imgPath) { 27 //保证最小为70*25的大小 28 int codeWidth = Math.max(70, width); 29 int codeHeight = Math.max(25, height); 30 try { 31 //使用EAN_13编码格式进行编码 32 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, 33 BarcodeFormat.EAN_13, codeWidth, codeHeight, null); 34 //生成png格式的图片保存到imgPath路径 35 MatrixToImageWriter.writeToStream(bitMatrix, "png", 36 new FileOutputStream(imgPath)); 37 System.out.println("encode success! the img's path is "+imgPath); 38 } catch (Exception e) { 39 e.printStackTrace(); 40 } 41 } 42 43 /** 44 * 解析条形码 45 * @param imgPath 46 * @return 47 */ 48 public String decode(String imgPath) { 49 BufferedImage image = null; 50 Result result = null; 51 try { 52 image = ImageIO.read(new File(imgPath)); 53 if (image == null) { 54 System.out.println("the decode image may be not exit."); 55 } 56 LuminanceSource source = new BufferedImageLuminanceSource(image); 57 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 58 59 result = new MultiFormatReader().decode(bitmap, null); 60 return result.getText(); 61 } catch (Exception e) { 62 e.printStackTrace(); 63 } 64 return null; 65 } 66 67 public static void main(String[] args) { 68 String decodeImgPath = "D:/1.png"; 69 ZxingEAN13Code EAN13Code = new ZxingEAN13Code(); 70 System.out.println(EAN13Code.decode(decodeImgPath)); 71 72 String encodeImgPath = "D:/2.png"; 73 String contents = "6923450657713"; 74 int width = 150, height = 40; 75 EAN13Code.encode(contents, width, height, encodeImgPath); 76 } 77 }
2:在web项目中很少会用到解码,一般而言是生成条形码后显示到页面或者打印出来,使用扫码枪扫码出来条形码的信息进行进一步的处理
在此说明:扫码枪扫描条形码很简单,其实就可以把扫码枪理解成键盘,扫描条形码后,就可以将条码中的信息(如:6923450657713)显示在光标定位的地方
1 import java.awt.image.BufferedImage; 2 import java.io.File; 3 import java.io.IOException; 4 import java.util.Hashtable; 5 6 import javax.imageio.ImageIO; 7 import javax.servlet.ServletOutputStream; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 import org.apache.struts.action.ActionForm; 12 import org.apache.struts.action.ActionMapping; 13 14 import com.google.zxing.BarcodeFormat; 15 import com.google.zxing.EncodeHintType; 16 import com.google.zxing.MultiFormatWriter; 17 import com.google.zxing.WriterException; 18 import com.google.zxing.client.j2se.MatrixToImageWriter; 19 import com.google.zxing.common.BitMatrix; 20 21 public class ZxingBarCodeUtil { 22 /** 23 * 根据字符串生成条形码 24 * 25 * @param code字符串 26 * @return 27 */ 28 public static BitMatrix getShapeCode(String code) { 29 // 编码条形码 30 Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); 31 hints.put(EncodeHintType.CHARACTER_SET, "GBK"); 32 BitMatrix matrix = null; 33 try { 34 // 使用code_128格式进行编码生成100*25的条形码 35 matrix = new MultiFormatWriter().encode(code, 36 BarcodeFormat.CODE_128, 100, 25, hints); 37 } catch (WriterException e) { 38 e.printStackTrace(); 39 } 40 return matrix; 41 } 42 43 /** 获取条形码 */ 44 public void getShapeCode(ActionMapping mapping, ActionForm form, 45 HttpServletRequest request, HttpServletResponse response) { 46 BitMatrix matrix = this.getShapeCode(request.getParameter("printCode")); 47 // 返回png图片流 48 // 获得Servlet输出流 49 ServletOutputStream outStream = null; 50 try { 51 outStream = response.getOutputStream(); 52 ImageIO.write(MatrixToImageWriter.toBufferedImage(matrix), "png", 53 outStream); 54 outStream.flush(); 55 // 关闭输出流 56 outStream.close(); 57 } catch (IOException e) { 58 String simplename = e.getClass().getSimpleName(); 59 if (!"ClientAbortException".equals(simplename)) { 60 e.printStackTrace(); 61 } 62 } 63 } 64 65 /*public static void main(String[] args) { 66 BufferedImage buff = MatrixToImageWriter 67 .toBufferedImage(getShapeCode("TG201603280003"));// 123 68 try { 69 ImageIO.write(buff, "png", new File("D://1.png")); 70 System.out.println("已生成"); 71 } catch (IOException e) { 72 e.printStackTrace(); 73 } 74 }*/ 75 }
3:二维码的生成与解码
1 import java.awt.image.BufferedImage; 2 import java.io.File; 3 import java.io.FileOutputStream; 4 import java.util.Hashtable; 5 6 import javax.imageio.ImageIO; 7 8 import com.google.zxing.BarcodeFormat; 9 import com.google.zxing.BinaryBitmap; 10 import com.google.zxing.DecodeHintType; 11 import com.google.zxing.EncodeHintType; 12 import com.google.zxing.LuminanceSource; 13 import com.google.zxing.MultiFormatReader; 14 import com.google.zxing.MultiFormatWriter; 15 import com.google.zxing.Result; 16 import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 17 import com.google.zxing.client.j2se.MatrixToImageWriter; 18 import com.google.zxing.common.BitMatrix; 19 import com.google.zxing.common.HybridBinarizer; 20 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 21 22 /** 23 * 二维码生成/解码器 24 */ 25 public class ZxingQRCode { 26 27 /** 28 * 生成二维码 29 * @param contents 30 * @param width 31 * @param height 32 * @param imgPath 33 */ 34 public void encode(String contents, int width, int height, String imgPath) { 35 Hashtable<EncodeHintType, Object> hints = new Hashtable(); 36 // 指定纠错等级 37 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); 38 // 指定显示格式为GBK 39 hints.put(EncodeHintType.CHARACTER_SET, "GBK"); 40 try { 41 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, 42 BarcodeFormat.QR_CODE, width, height, hints); 43 //生成png格式的图片保存到imgPath路径位置 44 MatrixToImageWriter.writeToStream(bitMatrix, "png", 45 new FileOutputStream(imgPath)); 46 System.out.println("QR Code encode sucsess! the img's path is "+imgPath); 47 } catch (Exception e) { 48 e.printStackTrace(); 49 } 50 } 51 52 /** 53 * 解析二维码 54 * @param imgPath 55 * @return 56 */ 57 public String decode(String imgPath) { 58 BufferedImage image = null; 59 Result result = null; 60 try { 61 //读取图片 62 image = ImageIO.read(new File(imgPath)); 63 if (image == null) { 64 System.out.println("the decode image may be not exit."); 65 } 66 LuminanceSource source = new BufferedImageLuminanceSource(image); 67 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 68 69 Hashtable<DecodeHintType, Object> hints = new Hashtable(); 70 //设置显示格式为GBK 71 hints.put(DecodeHintType.CHARACTER_SET, "GBK"); 72 //进行解码 73 result = new MultiFormatReader().decode(bitmap, hints); 74 return result.getText();//返回结果信息 75 } catch (Exception e) { 76 e.printStackTrace(); 77 } 78 return null; 79 } 80 81 public static void main(String[] args) { 82 ZxingQRCode ORCode = new ZxingQRCode(); 83 ORCode.encode("http://www.cnblogs.com/zhaoyhBlog/", 150, 150, 84 "D:/二维码1.png"); 85 86 System.out.println(ORCode.decode("D:/二维码1.png")); 87 } 88 }
二、使用org.jbarcode(jar包下载)
1、生成条形码(条形码下方包含 本身的含义,即:条码下方有数字字母等)
1 import java.awt.image.BufferedImage; 2 import java.io.FileOutputStream; 3 import org.jbarcode.JBarcode; 4 import org.jbarcode.encode.EAN8Encoder; 5 import org.jbarcode.paint.EAN8TextPainter; 6 import org.jbarcode.paint.WidthCodedPainter; 7 import org.jbarcode.util.ImageUtil; 8 9 /** 10 * 支持EAN13, EAN8, UPCA, UPCE, Code 3 of 9, Codabar, Code 11, Code 93, Code 128, 11 * MSI/Plessey, Interleaved 2 of PostNet等 12 */ 13 public class JBarcodeByEAN8Util { 14 15 public void encodeByEAN8(String content, String imgPath, int with, 16 int height) { 17 try { 18 JBarcode jBarcode = new JBarcode(EAN8Encoder.getInstance(), 19 WidthCodedPainter.getInstance(), EAN8TextPainter.getInstance()); 20 BufferedImage bufferedImage = jBarcode.createBarcode(content); 21 FileOutputStream outputStream = new FileOutputStream(imgPath); 22 ImageUtil.encodeAndWrite(bufferedImage, "jpeg", outputStream, with,height); 23 outputStream.close(); 24 System.out.println("==="); 25 } catch (Exception localException) { 26 localException.printStackTrace(); 27 } 28 } 29 30 public static void main(String[] paramArrayOfString) { 31 JBarcodeByEAN8Util jBarCodeUtil = new JBarcodeByEAN8Util(); 32 jBarCodeUtil.encodeByEAN8("110120119", "D:/EAN8.jpg", 100, 70); 33 } 34 }