java生成两种二维码

转载自:http://blog.csdn.net/hao134838/article/details/53895672

  引言


   在这篇博客中关于二维码的基本原理先不做介绍,先介绍我们怎样利用Java语言实现二维码的生成,现在二维


码在我们生活中已经非常常见了,一言不合就扫码!所以对于我们这帮程序猿来说,需要研究一把这个东西是怎么生


成,今天小编就给大家介绍一下,怎样一步一步生成二维码的。


  在这给大家介绍两种二维码,也是我们在生活中非常常见的两种,一种就是中间没有LOGO的二维码,一种是中间


带有logo的,当然现在第二种带有logo的二维码是非常常见的。


  我们需要引用两个jar包:core-3.1.0.jar和Qrcode_swetake.jar


 第一个java包也即是zxing.jar 包, 我这里用的是3.0 版本的core包,是Goole开发的,第二个jar包是用来解码的


  下面是整个demo的目录结构


                   



   核心类(BufferedImageLuminanceSource)代码:


[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.dmsd.demo;  
  2.   
  3. import java.awt.Graphics2D;  
  4. import java.awt.geom.AffineTransform;  
  5. import java.awt.image.BufferedImage;  
  6.   
  7. import com.google.zxing.LuminanceSource;  
  8.   
  9. public 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,  
  20.             int width, int height) {  
  21.         super(width, height);  
  22.   
  23.         int sourceWidth = image.getWidth();  
  24.         int sourceHeight = image.getHeight();  
  25.         if (left + width > sourceWidth || top + height > sourceHeight) {  
  26.             throw new IllegalArgumentException(  
  27.                     "Crop rectangle does not fit within image data.");  
  28.         }  
  29.   
  30.         for (int y = top; y < top + height; y++) {  
  31.             for (int x = left; x < left + width; x++) {  
  32.                 if ((image.getRGB(x, y) & 0xFF000000) == 0) {  
  33.                     image.setRGB(x, y, 0xFFFFFFFF); // = white  
  34.                 }  
  35.             }  
  36.         }  
  37.   
  38.         this.image = new BufferedImage(sourceWidth, sourceHeight,  
  39.                 BufferedImage.TYPE_BYTE_GRAY);  
  40.         this.image.getGraphics().drawImage(image, 00null);  
  41.         this.left = left;  
  42.         this.top = top;  
  43.     }  
  44.   
  45.     @Override  
  46.     public byte[] getRow(int y, byte[] row) {  
  47.         if (y < 0 || y >= getHeight()) {  
  48.             throw new IllegalArgumentException(  
  49.                     "Requested row is outside the image: " + y);  
  50.         }  
  51.         int width = getWidth();  
  52.         if (row == null || row.length < width) {  
  53.             row = new byte[width];  
  54.         }  
  55.         image.getRaster().getDataElements(left, top + y, width, 1, row);  
  56.         return row;  
  57.     }  
  58.   
  59.     @Override  
  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.     @Override  
  70.     public boolean isCropSupported() {  
  71.         return true;  
  72.     }  
  73.   
  74.     @Override  
  75.     public LuminanceSource crop(int left, int top, int width, int height) {  
  76.         return new BufferedImageLuminanceSource(image, this.left + left,  
  77.                 this.top + top, width, height);  
  78.     }  
  79.   
  80.     @Override  
  81.     public boolean isRotateSupported() {  
  82.         return true;  
  83.     }  
  84.   
  85.     @Override  
  86.     public LuminanceSource rotateCounterClockwise() {  
  87.   
  88.         int sourceWidth = image.getWidth();  
  89.         int sourceHeight = image.getHeight();  
  90.   
  91.         AffineTransform transform = new AffineTransform(0.0, -1.01.00.0,  
  92.                 0.0, sourceWidth);  
  93.   
  94.         BufferedImage rotatedImage = new BufferedImage(sourceHeight,  
  95.                 sourceWidth, BufferedImage.TYPE_BYTE_GRAY);  
  96.   
  97.         Graphics2D g = rotatedImage.createGraphics();  
  98.         g.drawImage(image, transform, null);  
  99.         g.dispose();  
  100.   
  101.         int width = getWidth();  
  102.         return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth  
  103.                 - (left + width), getHeight(), width);  
  104.     }  
  105.   
  106. }  


  核心类(MatrixToImageWriter)代码:


  

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.dmsd.demo;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. import java.io.File;  
  5. import java.io.IOException;  
  6. import java.io.OutputStream;  
  7.   
  8. import javax.imageio.ImageIO;  
  9.   
  10. import com.google.zxing.common.BitMatrix;  
  11.   
  12. public class MatrixToImageWriter {  
  13.     private static final int BLACK = 0xFF000000;  
  14.     private static final int WHITE = 0xFFFFFFFF;  
  15.   
  16.     private MatrixToImageWriter() {  
  17.     }  
  18.   
  19.     public static BufferedImage toBufferedImage(BitMatrix matrix) {  
  20.         int width = matrix.getWidth();  
  21.         int height = matrix.getHeight();  
  22.         BufferedImage image = new BufferedImage(width, height,  
  23.                 BufferedImage.TYPE_INT_RGB);  
  24.         for (int x = 0; x < width; x++) {  
  25.             for (int y = 0; y < height; y++) {  
  26.                 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);  
  27.             }  
  28.         }  
  29.         return image;  
  30.     }  
  31.   
  32.     public static void writeToFile(BitMatrix matrix, String format, File file)  
  33.             throws IOException {  
  34.         BufferedImage image = toBufferedImage(matrix);  
  35.         if (!ImageIO.write(image, format, file)) {  
  36.             throw new IOException("Could not write an image of format "  
  37.                     + format + " to " + file);  
  38.         }  
  39.     }  
  40.   
  41.     public static void writeToStream(BitMatrix matrix, String format,  
  42.             OutputStream stream) throws IOException {  
  43.         BufferedImage image = toBufferedImage(matrix);  
  44.         if (!ImageIO.write(image, format, stream)) {  
  45.             throw new IOException("Could not write an image of format "  
  46.                     + format);  
  47.         }  
  48.     }  
  49.   
  50. }  


   核心类(QRCodeUtil)代码:


  

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.dmsd.demo;  
  2.   
  3. import java.awt.BasicStroke;  
  4. import java.awt.Graphics;  
  5. import java.awt.Graphics2D;  
  6. import java.awt.Image;  
  7. import java.awt.Shape;  
  8. import java.awt.geom.RoundRectangle2D;  
  9. import java.awt.image.BufferedImage;  
  10. import java.io.File;  
  11. import java.io.OutputStream;  
  12. import java.util.Hashtable;  
  13. import java.util.Random;  
  14.   
  15. import javax.imageio.ImageIO;  
  16.   
  17. import com.google.zxing.BarcodeFormat;  
  18. import com.google.zxing.BinaryBitmap;  
  19. import com.google.zxing.DecodeHintType;  
  20. import com.google.zxing.EncodeHintType;  
  21. import com.google.zxing.MultiFormatReader;  
  22. import com.google.zxing.MultiFormatWriter;  
  23. import com.google.zxing.Result;  
  24. import com.google.zxing.common.BitMatrix;  
  25. import com.google.zxing.common.HybridBinarizer;  
  26. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  27.   
  28. public class QRCodeUtil {  
  29.   
  30.      private static final String CHARSET = "utf-8";    
  31.         private static final String FORMAT_NAME = "JPG";    
  32.         // 二维码尺寸    
  33.         private static final int QRCODE_SIZE = 300;    
  34.         // LOGO宽度    
  35.         private static final int WIDTH = 60;    
  36.         // LOGO高度    
  37.         private static final int HEIGHT = 60;    
  38.         
  39.         private static BufferedImage createImage(String content, String imgPath,    
  40.                 boolean needCompress) throws Exception {    
  41.             Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();    
  42.             hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);    
  43.             hints.put(EncodeHintType.CHARACTER_SET, CHARSET);    
  44.             hints.put(EncodeHintType.MARGIN, 1);    
  45.             BitMatrix bitMatrix = new MultiFormatWriter().encode(content,    
  46.                     BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);    
  47.             int width = bitMatrix.getWidth();    
  48.             int height = bitMatrix.getHeight();    
  49.             BufferedImage image = new BufferedImage(width, height,    
  50.                     BufferedImage.TYPE_INT_RGB);    
  51.             for (int x = 0; x < width; x++) {    
  52.                 for (int y = 0; y < height; y++) {    
  53.                     image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000    
  54.                             : 0xFFFFFFFF);    
  55.                 }    
  56.             }    
  57.             if (imgPath == null || "".equals(imgPath)) {    
  58.                 return image;    
  59.             }    
  60.             // 插入图片    
  61.             QRCodeUtil.insertImage(image, imgPath, needCompress);    
  62.             return image;    
  63.         }    
  64.         
  65.         /**  
  66.          * 插入LOGO  
  67.          *   
  68.          * @param source  
  69.          *            二维码图片  
  70.          * @param imgPath  
  71.          *            LOGO图片地址  
  72.          * @param needCompress  
  73.          *            是否压缩  
  74.          * @throws Exception  
  75.          */    
  76.         private static void insertImage(BufferedImage source, String imgPath,    
  77.                 boolean needCompress) throws Exception {    
  78.             File file = new File(imgPath);    
  79.             if (!file.exists()) {    
  80.                 System.err.println(""+imgPath+"   该文件不存在!");    
  81.                 return;    
  82.             }    
  83.             Image src = ImageIO.read(new File(imgPath));    
  84.             int width = src.getWidth(null);    
  85.             int height = src.getHeight(null);    
  86.             if (needCompress) { // 压缩LOGO    
  87.                 if (width > WIDTH) {    
  88.                     width = WIDTH;    
  89.                 }    
  90.                 if (height > HEIGHT) {    
  91.                     height = HEIGHT;    
  92.                 }    
  93.                 Image image = src.getScaledInstance(width, height,    
  94.                         Image.SCALE_SMOOTH);    
  95.                 BufferedImage tag = new BufferedImage(width, height,    
  96.                         BufferedImage.TYPE_INT_RGB);    
  97.                 Graphics g = tag.getGraphics();    
  98.                 g.drawImage(image, 00null); // 绘制缩小后的图    
  99.                 g.dispose();    
  100.                 src = image;    
  101.             }    
  102.             // 插入LOGO    
  103.             Graphics2D graph = source.createGraphics();    
  104.             int x = (QRCODE_SIZE - width) / 2;    
  105.             int y = (QRCODE_SIZE - height) / 2;    
  106.             graph.drawImage(src, x, y, width, height, null);    
  107.             Shape shape = new RoundRectangle2D.Float(x, y, width, width, 66);    
  108.             graph.setStroke(new BasicStroke(3f));    
  109.             graph.draw(shape);    
  110.             graph.dispose();    
  111.         }    
  112.         
  113.         /**  
  114.          * 生成二维码(内嵌LOGO)  
  115.          *   
  116.          * @param content  
  117.          *            内容  
  118.          * @param imgPath  
  119.          *            LOGO地址  
  120.          * @param destPath  
  121.          *            存放目录  
  122.          * @param needCompress  
  123.          *            是否压缩LOGO  
  124.          * @throws Exception  
  125.          */    
  126.         public static void encode(String content, String imgPath, String destPath,    
  127.                 boolean needCompress) throws Exception {    
  128.             BufferedImage image = QRCodeUtil.createImage(content, imgPath,    
  129.                     needCompress);    
  130.             mkdirs(destPath);    
  131.             String file = new Random().nextInt(99999999)+".jpg";    
  132.             ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));    
  133.         }    
  134.         
  135.         /**  
  136.          * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)  
  137.          * @author lanyuan  
  138.          * Email: [email protected]  
  139.          * @date 2013-12-11 上午10:16:36  
  140.          * @param destPath 存放目录  
  141.          */    
  142.         public static void mkdirs(String destPath) {    
  143.             File file =new File(destPath);        
  144.             //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)    
  145.             if (!file.exists() && !file.isDirectory()) {    
  146.                 file.mkdirs();    
  147.             }    
  148.         }    
  149.         
  150.         /**  
  151.          * 生成二维码(内嵌LOGO)  
  152.          *   
  153.          * @param content  
  154.          *            内容  
  155.          * @param imgPath  
  156.          *            LOGO地址  
  157.          * @param destPath  
  158.          *            存储地址  
  159.          * @throws Exception  
  160.          */    
  161.         public static void encode(String content, String imgPath, String destPath)    
  162.                 throws Exception {    
  163.             QRCodeUtil.encode(content, imgPath, destPath, false);    
  164.         }    
  165.         
  166.         /**  
  167.          * 生成二维码  
  168.          *   
  169.          * @param content  
  170.          *            内容  
  171.          * @param destPath  
  172.          *            存储地址  
  173.          * @param needCompress  
  174.          *            是否压缩LOGO  
  175.          * @throws Exception  
  176.          */    
  177.         public static void encode(String content, String destPath,    
  178.                 boolean needCompress) throws Exception {    
  179.             QRCodeUtil.encode(content, null, destPath, needCompress);    
  180.         }    
  181.         
  182.         /**  
  183.          * 生成二维码  
  184.          *   
  185.          * @param content  
  186.          *            内容  
  187.          * @param destPath  
  188.          *            存储地址  
  189.          * @throws Exception  
  190.          */    
  191.         public static void encode(String content, String destPath) throws Exception {    
  192.             QRCodeUtil.encode(content, null, destPath, false);    
  193.         }    
  194.         
  195.         /**  
  196.          * 生成二维码(内嵌LOGO)  
  197.          *   
  198.          * @param content  
  199.          *            内容  
  200.          * @param imgPath  
  201.          *            LOGO地址  
  202.          * @param output  
  203.          *            输出流  
  204.          * @param needCompress  
  205.          *            是否压缩LOGO  
  206.          * @throws Exception  
  207.          */    
  208.         public static void encode(String content, String imgPath,    
  209.                 OutputStream output, boolean needCompress) throws Exception {    
  210.             BufferedImage image = QRCodeUtil.createImage(content, imgPath,    
  211.                     needCompress);    
  212.             ImageIO.write(image, FORMAT_NAME, output);    
  213.         }    
  214.         
  215.         /**  
  216.          * 生成二维码  
  217.          *   
  218.          * @param content  
  219.          *            内容  
  220.          * @param output  
  221.          *            输出流  
  222.          * @throws Exception  
  223.          */    
  224.         public static void encode(String content, OutputStream output)    
  225.                 throws Exception {    
  226.             QRCodeUtil.encode(content, null, output, false);    
  227.         }    
  228.         
  229.         /**  
  230.          * 解析二维码  
  231.          *   
  232.          * @param file  
  233.          *            二维码图片  
  234.          * @return  
  235.          * @throws Exception  
  236.          */    
  237.         public static String decode(File file) throws Exception {    
  238.             BufferedImage image;    
  239.             image = ImageIO.read(file);    
  240.             if (image == null) {    
  241.                 return null;    
  242.             }    
  243.             BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(    
  244.                     image);    
  245.             BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));    
  246.             Result result;    
  247.             Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();    
  248.             hints.put(DecodeHintType.CHARACTER_SET, CHARSET);    
  249.             result = new MultiFormatReader().decode(bitmap, hints);    
  250.             String resultStr = result.getText();    
  251.             return resultStr;    
  252.         }    
  253.         
  254.         /**  
  255.          * 解析二维码  
  256.          *   
  257.          * @param path  
  258.          *            二维码图片地址  
  259.          * @return  
  260.          * @throws Exception  
  261.          */    
  262.         public static String decode(String path) throws Exception {    
  263.             return QRCodeUtil.decode(new File(path));    
  264.         }    
  265.         
  266.         public static void main(String[] args) throws Exception {    
  267.             String text = "薯 灯可分列式本上楞珂要瓜熟蒂落!000000000000000";    
  268.             QRCodeUtil.encode(text, "c:/df.jsp""c:/a/"true);    
  269.         }    
  270.   
  271. }  


   不带有logo的测试类(mytest):


   

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.dmsd.demo;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7.   
  8. import com.google.zxing.BarcodeFormat;  
  9. import com.google.zxing.EncodeHintType;  
  10. import com.google.zxing.MultiFormatWriter;  
  11. import com.google.zxing.WriterException;  
  12. import com.google.zxing.common.BitMatrix;  
  13.   
  14. public class MyTest {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      */  
  19.     public static void main(String[] args) {  
  20.          try {  
  21.             String content = "https://www.baidu.com";  
  22.              String path = "E:/";  
  23.                
  24.              MultiFormatWriter multiFormatWriter = new MultiFormatWriter();  
  25.              Map hints = new HashMap();  
  26.              hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
  27.              BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400400,hints);  
  28.              File file1 = new File(path,"01.jpg");  
  29.              MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file1);  
  30.         } catch (WriterException e) {  
  31.             e.printStackTrace();  
  32.         } catch (IOException e) {  
  33.             e.printStackTrace();  
  34.         }  
  35.     }    
  36.   
  37. }  


   带有logo测试类(TestLogo)代码:


 

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.dmsd.demo;  
  2.   
  3. public class TestLogo {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         try {  
  10.             String text = "https://www.baidu.com";    
  11.             QRCodeUtil.encode(text, "e:/001.jpg""e:/image/"true);  
  12.         } catch (Exception e) {  
  13.             e.printStackTrace();  
  14.         }    
  15.     }  
  16.   
  17. }  

猜你喜欢

转载自blog.csdn.net/lishk314/article/details/72413999