使用Google的ZXing库实现编解码二维码

慕课网讲解

http://www.imooc.com/learn/531


导入包

1.首先建立一个实现LuminanceSource的类

[html]  view plain  copy
  1. /**  
  2.  * @FileName: BufferedImageLuminanceSource.java  
  3.  * @Author  
  4.  * @Description:  
  5.  * @Date 2016年7月1日 下午11:43:33  
  6.  * @CopyRight ZTE Corporation  
  7.  */  
  8. package com.xsy.qrcode.google.zxing;  
  9.   
  10. import java.awt.Graphics2D;  
  11. import java.awt.geom.AffineTransform;  
  12. import java.awt.image.BufferedImage;  
  13.   
  14. import com.google.zxing.LuminanceSource;  
  15.   
  16. public class BufferedImageLuminanceSource extends LuminanceSource{  
  17.     private final BufferedImage image;  
  18.     private final int           left;  
  19.     private final int           top;  
  20.   
  21.     public BufferedImageLuminanceSource(BufferedImage image){  
  22.         this(image, 0, 0, image.getWidth(), image.getHeight());  
  23.     }  
  24.   
  25.     public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height){  
  26.         super(width, height);  
  27.   
  28.         int sourceWidth = image.getWidth();  
  29.         int sourceHeight = image.getHeight();  
  30.         if(left + width > sourceWidth || top + height > sourceHeight){  
  31.             throw new IllegalArgumentException("Crop rectangle does not fit within image data.");  
  32.         }  
  33.   
  34.         for(int y = top; y < top + height; y++){  
  35.             for(int x = left; x < left + width; x++){  
  36.                 if((image.getRGB(x, y) & 0xFF000000) == 0){  
  37.                     image.setRGB(x, y, 0xFFFFFFFF); // = white  
  38.                 }  
  39.             }  
  40.         }  
  41.   
  42.         this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);  
  43.         this.image.getGraphics().drawImage(image, 0, 0, null);  
  44.         this.left = left;  
  45.         this.top = top;  
  46.     }  
  47.   
  48.     public byte[] getRow(int y, byte[] row){  
  49.         if(y < 0 || y >= getHeight()){  
  50.             throw new IllegalArgumentException("Requested row is outside the image: " + y);  
  51.         }  
  52.         int width = getWidth();  
  53.         if(row == null || row.length < width){  
  54.             row = new byte[width];  
  55.         }  
  56.         image.getRaster().getDataElements(left, top + y, width, 1, row);  
  57.         return row;  
  58.     }  
  59.   
  60.     public byte[] getMatrix(){  
  61.         int width = getWidth();  
  62.         int height = getHeight();  
  63.         int area = width * height;  
  64.         byte[] matrix = new byte[area];  
  65.         image.getRaster().getDataElements(left, top, width, height, matrix);  
  66.         return matrix;  
  67.     }  
  68.   
  69.     public boolean isCropSupported(){  
  70.         return true;  
  71.     }  
  72.   
  73.     public LuminanceSource crop(int left, int top, int width, int height){  
  74.         return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);  
  75.     }  
  76.   
  77.     public boolean isRotateSupported(){  
  78.         return true;  
  79.     }  
  80.   
  81.     public LuminanceSource rotateCounterClockwise(){  
  82.         int sourceWidth = image.getWidth();  
  83.         int sourceHeight = image.getHeight();  
  84.         AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);  
  85.         BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);  
  86.         Graphics2D g = rotatedImage.createGraphics();  
  87.         g.drawImage(image, transform, null);  
  88.         g.dispose();  
  89.         int width = getWidth();  
  90.         return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);  
  91.     }  
  92. }  


2.再创建编解码的工具类

[html]  view plain  copy
  1. /**  
  2.  * @FileName: QRCodeUtil.java  
  3.  * @Author  
  4.  * @Description:  
  5.  * @Date 2016年7月1日 下午11:45:25  
  6.  * @CopyRight ZTE Corporation  
  7.  */  
  8. package com.xsy.qrcode.google.zxing;  
  9.   
  10. import java.awt.BasicStroke;  
  11. import java.awt.Graphics;  
  12. import java.awt.Graphics2D;  
  13. import java.awt.Image;  
  14. import java.awt.Shape;  
  15. import java.awt.geom.RoundRectangle2D;  
  16. import java.awt.image.BufferedImage;  
  17. import java.io.File;  
  18. import java.io.OutputStream;  
  19. import java.util.Hashtable;  
  20. import java.util.Random;  
  21.   
  22. import javax.imageio.ImageIO;  
  23.   
  24. import com.google.zxing.BarcodeFormat;  
  25. import com.google.zxing.BinaryBitmap;  
  26. import com.google.zxing.DecodeHintType;  
  27. import com.google.zxing.EncodeHintType;  
  28. import com.google.zxing.MultiFormatReader;  
  29. import com.google.zxing.MultiFormatWriter;  
  30. import com.google.zxing.Result;  
  31. import com.google.zxing.common.BitMatrix;  
  32. import com.google.zxing.common.HybridBinarizer;  
  33. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  34.   
  35. public class QRCodeUtil{  
  36.   
  37.     private static final String CHARSET     = "utf-8";  
  38.     private static final String FORMAT_NAME = "JPG";  
  39.     // 二维码尺寸  
  40.     private static final int    QRCODE_SIZE = 300;  
  41.     // LOGO宽度  
  42.     private static final int    WIDTH       = 60;  
  43.     // LOGO高度  
  44.     private static final int    HEIGHT      = 60;  
  45.   
  46.     @SuppressWarnings({ "unchecked", "rawtypes" })  
  47.     private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception{  
  48.         Hashtable hints = new Hashtable();  
  49.         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
  50.         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);  
  51.         hints.put(EncodeHintType.MARGIN, 1);  
  52.         BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,  
  53.                                                              hints);  
  54.         int width = bitMatrix.getWidth();  
  55.         int height = bitMatrix.getHeight();  
  56.         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  57.         for(int x = 0; x < width; x++){  
  58.             for(int y = 0; y < height; y++){  
  59.                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);  
  60.             }  
  61.         }  
  62.         if(imgPath == null || "".equals(imgPath)){  
  63.             return image;  
  64.         }  
  65.         // 插入图片  
  66.         QRCodeUtil.insertImage(image, imgPath, needCompress);  
  67.         return image;  
  68.     }  
  69.   
  70.     private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception{  
  71.         File file = new File(imgPath);  
  72.         if(!file.exists()){  
  73.             System.err.println("" + imgPath + "   该文件不存在!");  
  74.             return;  
  75.         }  
  76.         Image src = ImageIO.read(new File(imgPath));  
  77.         int width = src.getWidth(null);  
  78.         int height = src.getHeight(null);  
  79.         if(needCompress){ // 压缩LOGO  
  80.             if(width > WIDTH){  
  81.                 width = WIDTH;  
  82.             }  
  83.             if(height > HEIGHT){  
  84.                 height = HEIGHT;  
  85.             }  
  86.             Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);  
  87.             BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  88.             Graphics g = tag.getGraphics();  
  89.             g.drawImage(image, 0, 0, null); // 绘制缩小后的图  
  90.             g.dispose();  
  91.             src = image;  
  92.         }  
  93.         // 插入LOGO  
  94.         Graphics2D graph = source.createGraphics();  
  95.         int x = (QRCODE_SIZE - width) / 2;  
  96.         int y = (QRCODE_SIZE - height) / 2;  
  97.         graph.drawImage(src, x, y, width, height, null);  
  98.         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);  
  99.         graph.setStroke(new BasicStroke(3f));  
  100.         graph.draw(shape);  
  101.         graph.dispose();  
  102.     }  
  103.   
  104.     public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception{  
  105.         BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);  
  106.         mkdirs(destPath);  
  107.         String file = new Random().nextInt(99999999) + ".jpg";  
  108.         ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));  
  109.     }  
  110.   
  111.     public static void mkdirs(String destPath){  
  112.         File file = new File(destPath);  
  113.         // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)  
  114.         if(!file.exists() && !file.isDirectory()){  
  115.             file.mkdirs();  
  116.         }  
  117.     }  
  118.   
  119.     public static void encode(String content, String imgPath, String destPath) throws Exception{  
  120.         QRCodeUtil.encode(content, imgPath, destPath, false);  
  121.     }  
  122.   
  123.     public static void encode(String content, String destPath, boolean needCompress) throws Exception{  
  124.         QRCodeUtil.encode(content, null, destPath, needCompress);  
  125.     }  
  126.   
  127.     public static void encode(String content, String destPath) throws Exception{  
  128.         QRCodeUtil.encode(content, null, destPath, false);  
  129.     }  
  130.   
  131.     public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)  
  132.             throws Exception{  
  133.         BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);  
  134.         ImageIO.write(image, FORMAT_NAME, output);  
  135.     }  
  136.   
  137.     public static void encode(String content, OutputStream output) throws Exception{  
  138.         QRCodeUtil.encode(content, null, output, false);  
  139.     }  
  140.   
  141.     @SuppressWarnings({ "unchecked", "rawtypes" })  
  142.     public static String decode(File file) throws Exception{  
  143.         BufferedImage image;  
  144.         image = ImageIO.read(file);  
  145.         if(image == null){  
  146.             return null;  
  147.         }  
  148.         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);  
  149.         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));  
  150.         Result result;  
  151.         Hashtable hints = new Hashtable();  
  152.         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);  
  153.         result = new MultiFormatReader().decode(bitmap, hints);  
  154.         String resultStr = result.getText();  
  155.         return resultStr;  
  156.     }  
  157.   
  158.     public static String decode(String path) throws Exception{  
  159.         return QRCodeUtil.decode(new File(path));  
  160.     }  
  161.   
  162.     public static void main(String[] args) throws Exception{  
  163.         String text = "http://www.dans88.com.cn";  
  164.         QRCodeUtil.encode(text, "d:/MyWorkDoc/my180.jpg", "d:/MyWorkDoc", true);  
  165.     }  
  166.   
  167. }  


3.测试

[html]  view plain  copy
  1. /**  
  2.  * @FileName: QRCodeTest.java  
  3.  * @Author  
  4.  * @Description:  
  5.  * @Date 2016年7月1日 下午11:50:04  
  6.  * @CopyRight ZTE Corporation  
  7.  */  
  8. package com.xsy.qrcode.google.zxing;  
  9.   
  10. import org.junit.Test;  
  11.   
  12. public class QRCodeTest{  
  13.   
  14.     @Test  
  15.     /**  
  16.      *   
  17.      * @Title: testEncodeQRWithoutLogo  
  18.      * @Description:不带logo的图像  
  19.      */  
  20.     public void testEncodeQRWithoutLogo(){  
  21.         String text = "这是我的电话号码:15208384257";  
  22.         try{  
  23.             QRCodeUtil.encode(text, "", "d:/xsy", true);  
  24.         }  
  25.         catch(Exception e){  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29.   
  30.     @Test  
  31.     /**  
  32.      *   
  33.      * @Title: testEncodeQRWithLogo  
  34.      * @Description:带logo的图像  
  35.      */  
  36.     public void testEncodeQRWithLogo(){  
  37.         String text = "这是我的电话号码:15208384257";  
  38.         try{  
  39.             QRCodeUtil.encode(text, "d:/xsy/logo.png", "d:/xsy", true);  
  40.         }  
  41.         catch(Exception e){  
  42.             e.printStackTrace();  
  43.         }  
  44.     }  
  45.   
  46.     @Test  
  47.     public void testDecodeQR(){  
  48.         try{  
  49.             String content = QRCodeUtil.decode("d:/xsy/46647064.jpg");  
  50.             System.out.println(content);  
  51.         }  
  52.         catch(Exception e){  
  53.             e.printStackTrace();  
  54.         }  
  55.     }  
  56. }  

可以生成不带和带logo的二维码图片,并且可以和上一篇文章中的QRCode生成的二维码图片交叉编解码。



可以在网页中直接使用jQuery-qrcode来生成二维码

https://github.com/jeromeetienne/jquery-qrcode


java类代码 github https://github.com/1633788059/zXingImage



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值