Zxing和QR CODE 生成与解析二维码实例(带logo篇)

http://blog.csdn.net/gao36951/article/details/41149049


上一篇介绍了普通的二位码的生成与解析,本篇来介绍两种工具类生成带Logo的二维码的实例

下载jar包地址:http://download.csdn.net/detail/gao36951/8161861

首先介绍Zxing生成带logo的二维码

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

生成二维码类

[java]  view plain  copy
  1. package com.zxing.create;  
  2.   
  3. import java.awt.BasicStroke;  
  4. import java.awt.Color;  
  5. import java.awt.Component;  
  6. import java.awt.Graphics2D;  
  7. import java.awt.MediaTracker;  
  8. import java.awt.image.BufferedImage;  
  9. import java.io.File;  
  10. import java.io.OutputStream;  
  11. import java.util.Date;  
  12. import java.util.HashMap;  
  13. import java.util.Map;  
  14.   
  15. import javax.imageio.ImageIO;  
  16.   
  17. import com.google.zxing.BarcodeFormat;  
  18. import com.google.zxing.Binarizer;  
  19. import com.google.zxing.BinaryBitmap;  
  20. import com.google.zxing.EncodeHintType;  
  21. import com.google.zxing.LuminanceSource;  
  22. import com.google.zxing.MultiFormatReader;  
  23. import com.google.zxing.MultiFormatWriter;  
  24. import com.google.zxing.Result;  
  25. import com.google.zxing.WriterException;  
  26. import com.google.zxing.common.BitMatrix;  
  27. import com.google.zxing.common.HybridBinarizer;  
  28. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  29. import com.util.BufferedImageLuminanceSource;  
  30.   
  31. /**   
  32.  * @Description: (二维码)      
  33.  * @author:yqgao   
  34.  * @date:2014-11-7 下午05:27:13      
  35.  */  
  36. public class ZXingCode  
  37. {  
  38.     public static void main(String[] args) throws WriterException  
  39.     {  
  40.         String content = "http://blog.csdn.net/gao36951";  
  41.         String filePath = "D:/二维码生成/weixin.jpg";  
  42.         try  
  43.         {  
  44.             File file = new File(filePath);  
  45.    
  46.             ZXingCode zp = new ZXingCode();  
  47.    
  48.             BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 300300, zp.getDecodeHintType());  
  49.    
  50.             ImageIO.write(bim, "jpeg", file);  
  51.    
  52.             zp.addLogo_QRCode(file, new File("D:/logo/logo3.jpg"), new LogoConfig());  
  53.                
  54. //            Thread.sleep(5000);  
  55. //            zp.parseQR_CODEImage(new File("D:/二维码生成/TDC-test.png"));  
  56.         }  
  57.         catch (Exception e)  
  58.         {  
  59.             e.printStackTrace();  
  60.         }  
  61.     }  
  62.    
  63.     /** 
  64.      * 给二维码图片添加Logo 
  65.      * 
  66.      * @param qrPic 
  67.      * @param logoPic 
  68.      */  
  69.     public void addLogo_QRCode(File qrPic, File logoPic, LogoConfig logoConfig)  
  70.     {  
  71.         try  
  72.         {  
  73.             if (!qrPic.isFile() || !logoPic.isFile())  
  74.             {  
  75.                 System.out.print("file not find !");  
  76.                 System.exit(0);  
  77.             }  
  78.    
  79.             /** 
  80.              * 读取二维码图片,并构建绘图对象 
  81.              */  
  82.             BufferedImage image = ImageIO.read(qrPic);  
  83.             Graphics2D g = image.createGraphics();  
  84.    
  85.             /** 
  86.              * 读取Logo图片 
  87.              */  
  88.             BufferedImage logo = ImageIO.read(logoPic);  
  89.             /** 
  90.              * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码 
  91.              */  
  92.             int widthLogo = logo.getWidth(null)>image.getWidth()*2/10?(image.getWidth()*2/10):logo.getWidth(null),   
  93.                 heightLogo = logo.getHeight(null)>image.getHeight()*2/10?(image.getHeight()*2/10):logo.getHeight(null);  
  94.                
  95.             // 计算图片放置位置  
  96.             /** 
  97.              * logo放在中心 
  98.              */  
  99.             /* int x = (image.getWidth() - widthLogo) / 2; 
  100.                int y = (image.getHeight() - heightLogo) / 2;*/  
  101.              /** 
  102.              * logo放在右下角 
  103.              */  
  104.             int x = (image.getWidth() - widthLogo);  
  105.             int y = (image.getHeight() - heightLogo);  
  106.             //开始绘制图片  
  107.             g.drawImage(logo, x, y, widthLogo, heightLogo, null);  
  108.             g.drawRoundRect(x, y, widthLogo, heightLogo, 1515);  
  109.             g.setStroke(new BasicStroke(logoConfig.getBorder()));  
  110.             g.setColor(logoConfig.getBorderColor());  
  111.             g.drawRect(x, y, widthLogo, heightLogo);  
  112.                
  113.             g.dispose();  
  114.             logo.flush();  
  115.             image.flush();  
  116.                
  117.             ImageIO.write(image, "png"new File("D:/二维码生成/TDC-"/*+new Date().getTime()*/+"test.png"));  
  118.         }  
  119.         catch (Exception e)  
  120.         {  
  121.             e.printStackTrace();  
  122.         }  
  123.     }  
  124.    
  125.     /** 
  126.      * 二维码的解析 
  127.      * 
  128.      * @param file 
  129.      */  
  130.     public void parseQR_CODEImage(File file)  
  131.     {  
  132.         try  
  133.         {  
  134.             MultiFormatReader formatReader = new MultiFormatReader();  
  135.    
  136.             // File file = new File(filePath);  
  137.             if (!file.exists())  
  138.             {  
  139.                 return;  
  140.             }  
  141.    
  142.             BufferedImage image = ImageIO.read(file);  
  143.    
  144.             LuminanceSource source = new BufferedImageLuminanceSource(image);  
  145.             Binarizer binarizer = new HybridBinarizer(source);  
  146.             BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
  147.    
  148.             Map hints = new HashMap();  
  149.             hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
  150.    
  151.             Result result = formatReader.decode(binaryBitmap, hints);  
  152.    
  153.             System.out.println("result = " + result.toString());  
  154.             System.out.println("resultFormat = " + result.getBarcodeFormat());  
  155.             System.out.println("resultText = " + result.getText());  
  156.         }  
  157.         catch (Exception e)  
  158.         {  
  159.             e.printStackTrace();  
  160.         }  
  161.     }  
  162.    
  163.     /** 
  164.      * 将二维码生成为文件 
  165.      * 
  166.      * @param bm 
  167.      * @param imageFormat 
  168.      * @param file 
  169.      */  
  170.     public void decodeQR_CODE2ImageFile(BitMatrix bm, String imageFormat, File file)  
  171.     {  
  172.         try  
  173.         {  
  174.             if (null == file || file.getName().trim().isEmpty())  
  175.             {  
  176.                 throw new IllegalArgumentException("文件异常,或扩展名有问题!");  
  177.             }  
  178.    
  179.             BufferedImage bi = fileToBufferedImage(bm);  
  180.             ImageIO.write(bi, "apng", file);  
  181.         }  
  182.         catch (Exception e)  
  183.         {  
  184.             e.printStackTrace();  
  185.         }  
  186.     }  
  187.    
  188.    
  189.     /** 
  190.      * 构建初始化二维码 
  191.      * 
  192.      * @param bm 
  193.      * @return 
  194.      */  
  195.     public BufferedImage fileToBufferedImage(BitMatrix bm)  
  196.     {  
  197.         BufferedImage image = null;  
  198.         try  
  199.         {  
  200.             int w = bm.getWidth(), h = bm.getHeight();  
  201.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
  202.    
  203.             for (int x = 0; x < w; x++)  
  204.             {  
  205.                 for (int y = 0; y < h; y++)  
  206.                 {  
  207.                     image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);  
  208.                 }  
  209.             }  
  210.    
  211.         }  
  212.         catch (Exception e)  
  213.         {  
  214.             e.printStackTrace();  
  215.         }  
  216.         return image;  
  217.     }  
  218.    
  219.     /** 
  220.      * 生成二维码bufferedImage图片 
  221.      * 
  222.      * @param content 
  223.      *            编码内容 
  224.      * @param barcodeFormat 
  225.      *            编码类型 
  226.      * @param width 
  227.      *            图片宽度 
  228.      * @param height 
  229.      *            图片高度 
  230.      * @param hints 
  231.      *            设置参数 
  232.      * @return 
  233.      */  
  234.     public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)  
  235.     {  
  236.         MultiFormatWriter multiFormatWriter = null;  
  237.         BitMatrix bm = null;  
  238.         BufferedImage image = null;  
  239.         try  
  240.         {  
  241.             multiFormatWriter = new MultiFormatWriter();  
  242.    
  243.             // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数  
  244.             bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);  
  245.    
  246.             int w = bm.getWidth();  
  247.             int h = bm.getHeight();  
  248.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
  249.    
  250.             // 开始利用二维码数据创建Bitmap图片,分别设为白(0xFFFFFFFF)黑(0xFF000000)两色  
  251.             for (int x = 0; x < w; x++)  
  252.             {  
  253.                 for (int y = 0; y < h; y++)  
  254.                 {  
  255.                     image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);  
  256.                 }  
  257.             }  
  258.         }  
  259.         catch (WriterException e)  
  260.         {  
  261.             e.printStackTrace();  
  262.         }  
  263.         return image;  
  264.     }  
  265.    
  266.     /** 
  267.      * 设置二维码的格式参数 
  268.      * 
  269.      * @return 
  270.      */  
  271.     public Map<EncodeHintType, Object> getDecodeHintType()  
  272.     {  
  273.         // 用于设置QR二维码参数  
  274.         Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();  
  275.         // 设置QR二维码的纠错级别(H为最高级别)具体级别信息  
  276.         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
  277.         // 设置编码方式  
  278.         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
  279.         hints.put(EncodeHintType.MARGIN, 0);  
  280.         hints.put(EncodeHintType.MAX_SIZE, 350);  
  281.         hints.put(EncodeHintType.MIN_SIZE, 100);  
  282.    
  283.         return hints;  
  284.     }  
  285. }  
  286.    
  287. class LogoConfig  
  288. {  
  289.     // logo默认边框颜色  
  290.     public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;  
  291.     // logo默认边框宽度  
  292.     public static final int DEFAULT_BORDER = 2;  
  293.     // logo大小默认为照片的1/5  
  294.     public static final int DEFAULT_LOGOPART = 5;  
  295.    
  296.     private final int border = DEFAULT_BORDER;  
  297.     private final Color borderColor;  
  298.     private final int logoPart;  
  299.    
  300.     /** 
  301.      * Creates a default config with on color {@link #BLACK} and off color 
  302.      * {@link #WHITE}, generating normal black-on-white barcodes. 
  303.      */  
  304.     public LogoConfig()  
  305.     {  
  306.         this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);  
  307.     }  
  308.    
  309.     public LogoConfig(Color borderColor, int logoPart)  
  310.     {  
  311.         this.borderColor = borderColor;  
  312.         this.logoPart = logoPart;  
  313.     }  
  314.    
  315.     public Color getBorderColor()  
  316.     {  
  317.         return borderColor;  
  318.     }  
  319.    
  320.     public int getBorder()  
  321.     {  
  322.         return border;  
  323.     }  
  324.    
  325.     public int getLogoPart()  
  326.     {  
  327.         return logoPart;  
  328.     }  
  329. }  

生成的带logo的二维码如下图


下面介绍QR CODE 生成带Logo的二维码的实例

[java]  view plain  copy
  1. package com.qrcode.create;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Graphics2D;  
  5. import java.awt.Image;  
  6. import java.awt.image.BufferedImage;  
  7. import java.io.File;  
  8.   
  9. import javax.imageio.ImageIO;  
  10.   
  11. import com.swetake.util.Qrcode;  
  12.   
  13. /**  
  14.  * @作者  Relieved 
  15.  * @创建日期   2014年11月8日 
  16.  * @描述  (带logo二维码)  
  17.  * @版本 V 1.0 
  18.  */  
  19. public class Logo_Two_Code {  
  20. /**  
  21.      * 生成二维码(QRCode)图片  
  22.      * @param content 二维码图片的内容 
  23.      * @param imgPath 生成二维码图片完整的路径 
  24.      * @param ccbpath  二维码图片中间的logo路径 
  25.      */    
  26.     public static int createQRCode(String content, String imgPath,String ccbPath,int version) {    
  27.         try {    
  28.             Qrcode qrcodeHandler = new Qrcode();    
  29.             //设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小    
  30.             qrcodeHandler.setQrcodeErrorCorrect('M');    
  31.             //N代表数字,A代表字符a-Z,B代表其他字符  
  32.             qrcodeHandler.setQrcodeEncodeMode('B');   
  33.             // 设置设置二维码版本,取值范围1-40,值越大尺寸越大,可存储的信息越大    
  34.             qrcodeHandler.setQrcodeVersion(version);   
  35.             // 图片尺寸    
  36.             int imgSize =67 + 12 * (version - 1) ;  
  37.     
  38.             byte[] contentBytes = content.getBytes("gb2312");    
  39.             BufferedImage image = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);    
  40.             Graphics2D gs = image.createGraphics();    
  41.     
  42.             gs.setBackground(Color.WHITE);    
  43.             gs.clearRect(00, imgSize, imgSize);    
  44.     
  45.             // 设定图像颜色 > BLACK    
  46.             gs.setColor(Color.BLUE);    
  47.     
  48.             // 设置偏移量 不设置可能导致解析出错    
  49.             int pixoff = 2;    
  50.             // 输出内容 > 二维码    
  51.             if (contentBytes.length > 0 && contentBytes.length < 130) {  
  52.                 boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);  
  53.                 for (int i = 0; i < codeOut.length; i++) {  
  54.                     for (int j = 0; j < codeOut.length; j++) {  
  55.                         if (codeOut[j][i]) {  
  56.                             gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 33);  
  57.                         }  
  58.                     }  
  59.                 }  
  60.             } else {    
  61.                 System.err.println("QRCode content bytes length = "    
  62.                         + contentBytes.length + " not in [ 0,125]. ");    
  63.                 return -1;  
  64.             }    
  65.             Image logo = ImageIO.read(new File(ccbPath));//实例化一个Image对象。  
  66.             int widthLogo = logo.getWidth(null)>image.getWidth()*2/10?(image.getWidth()*2/10):logo.getWidth(null),   
  67.                 heightLogo = logo.getHeight(null)>image.getHeight()*2/10?(image.getHeight()*2/10):logo.getWidth(null);  
  68.              
  69.              /** 
  70.                * logo放在中心 
  71.               */  
  72.             int x = (image.getWidth() - widthLogo) / 2;  
  73.             int y = (image.getHeight() - heightLogo) / 2;  
  74.             gs.drawImage(logo, x, y, widthLogo, heightLogo, null);  
  75.             gs.dispose();    
  76.             image.flush();    
  77.     
  78.             // 生成二维码QRCode图片    
  79.             File imgFile = new File(imgPath);    
  80.             ImageIO.write(image, "png", imgFile);    
  81.     
  82.         } catch (Exception e)   
  83.         {    
  84.             e.printStackTrace();    
  85.             return -100;  
  86.         }    
  87.           
  88.         return 0;  
  89.     }    
  90.   
  91.   
  92.     public static void main(String[] args) {  
  93.     String imgPath = "D:/二维码生成/logo_QRCode.png";   
  94.     String logoPath = "D:/logo/logo3.jpg";  
  95.     String encoderContent = "http://blog.csdn.net/gao36951";  
  96.     Logo_Two_Code logo_Two_Code = new Logo_Two_Code();  
  97.     logo_Two_Code.createQRCode(encoderContent, imgPath, logoPath,8);  
  98. }  
  99. }  


生成带Logo的二维码如下图:


注意:

引用12楼

有一个问题是二维码的黑白颜色弄反了,导致扫一下无法识别,希望大家别犯这个错儿了……


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值