zoukankan      html  css  js  c++  java
  • java生成/解析二维码

      1 package a;
      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 /**
     29  * 二维码工具类
     30  * 
     31  */
     32 public class QRCodeUtil {
     33 
     34     private static final String CHARSET = "utf-8";
     35     private static final String FORMAT_NAME = "JPG";
     36     // 二维码尺寸
     37     private static final int QRCODE_SIZE = 300;
     38     // LOGO宽度
     39     private static final int WIDTH = 60;
     40     // LOGO高度
     41     private static final int HEIGHT = 60;
     42 
     43     private static BufferedImage createImage(String content, String imgPath,
     44             boolean needCompress) throws Exception {
     45         Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
     46         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置二维码纠错级别
     47         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
     48         hints.put(EncodeHintType.MARGIN, 1);// 设置两边空白区域
     49         // 创建比特矩阵(位矩阵)的QR码编码的字符串
     50         BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
     51                 BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
     52         // 使BufferedImage勾画QRCode (getWidth()得到的 是行二维码像素点)
     53         int width = bitMatrix.getWidth();
     54         int height = bitMatrix.getHeight();
     55         // 开始在缓冲图片中画二维码
     56         BufferedImage image = new BufferedImage(width, height,
     57                 BufferedImage.TYPE_INT_RGB);
     58         for (int x = 0; x < width; x++) {
     59             for (int y = 0; y < height; y++) {
     60                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
     61                         : 0xFFFFFFFF);
     62             }
     63         }
     64         if (imgPath == null || "".equals(imgPath)) {
     65             return image;
     66         }
     67         // 插入图片
     68         QRCodeUtil.insertImage(image, imgPath, needCompress);
     69         return image;
     70     }
     71 
     72     /**
     73      * 插入LOGO
     74      * 
     75      * @param source
     76      *            二维码图片
     77      * @param imgPath
     78      *            LOGO图片地址
     79      * @param needCompress
     80      *            是否压缩
     81      * @throws Exception
     82      */
     83     private static void insertImage(BufferedImage source, String imgPath,
     84             boolean needCompress) throws Exception {
     85         File file = new File(imgPath);
     86         if (!file.exists()) {
     87             System.err.println("" + imgPath + "   该文件不存在!");
     88             return;
     89         }
     90         Image src = ImageIO.read(new File(imgPath));
     91         int width = src.getWidth(null);
     92         int height = src.getHeight(null);
     93         if (needCompress) { // 压缩LOGO
     94             if (width > WIDTH) {
     95                 width = WIDTH;
     96             }
     97             if (height > HEIGHT) {
     98                 height = HEIGHT;
     99             }
    100             Image image = src.getScaledInstance(width, height,
    101                     Image.SCALE_SMOOTH);
    102             BufferedImage tag = new BufferedImage(width, height,
    103                     BufferedImage.TYPE_INT_RGB);
    104             Graphics g = tag.getGraphics();
    105             g.drawImage(image, 0, 0, null); // 绘制缩小后的图
    106             g.dispose();
    107             src = image;
    108         }
    109         // 插入LOGO
    110         Graphics2D graph = source.createGraphics();
    111         int x = (QRCODE_SIZE - width) / 2;
    112         int y = (QRCODE_SIZE - height) / 2;
    113         graph.drawImage(src, x, y, width, height, null);
    114         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
    115         graph.setStroke(new BasicStroke(3f));
    116         graph.draw(shape);
    117         graph.dispose();
    118     }
    119 
    120     /**
    121      * 生成二维码(内嵌LOGO)
    122      * 
    123      * @param content
    124      *            内容
    125      * @param imgPath
    126      *            LOGO地址
    127      * @param destPath
    128      *            存放目录
    129      * @param needCompress
    130      *            是否压缩LOGO
    131      * @throws Exception
    132      */
    133     public static void encode(String content, String imgPath, String destPath,
    134             boolean needCompress) throws Exception {
    135         BufferedImage image = QRCodeUtil.createImage(content, imgPath,
    136                 needCompress);
    137         mkdirs(destPath);
    138         String file = new Random().nextInt(99999999) + ".jpg";
    139         ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
    140     }
    141 
    142     /**
    143      * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    144      * 
    145      * @author
    146      * @date
    147      * @param destPath
    148      *            存放目录
    149      */
    150     public static void mkdirs(String destPath) {
    151         File file = new File(destPath);
    152         // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    153         if (!file.exists() && !file.isDirectory()) {
    154             file.mkdirs();
    155         }
    156     }
    157 
    158     /**
    159      * 生成二维码(内嵌LOGO)
    160      * 
    161      * @param content
    162      *            内容
    163      * @param imgPath
    164      *            LOGO地址
    165      * @param destPath
    166      *            存储地址
    167      * @throws Exception
    168      */
    169     public static void encode(String content, String imgPath, String destPath)
    170             throws Exception {
    171         QRCodeUtil.encode(content, imgPath, destPath, false);
    172     }
    173 
    174     /**
    175      * 生成二维码
    176      * 
    177      * @param content
    178      *            内容
    179      * @param destPath
    180      *            存储地址
    181      * @param needCompress
    182      *            是否压缩LOGO
    183      * @throws Exception
    184      */
    185     public static void encode(String content, String destPath,
    186             boolean needCompress) throws Exception {
    187         QRCodeUtil.encode(content, null, destPath, needCompress);
    188     }
    189 
    190     /**
    191      * 生成二维码
    192      * 
    193      * @param content
    194      *            内容
    195      * @param destPath
    196      *            存储地址
    197      * @throws Exception
    198      */
    199     public static void encode(String content, String destPath) throws Exception {
    200         QRCodeUtil.encode(content, null, destPath, false);
    201     }
    202 
    203     /**
    204      * 生成二维码(内嵌LOGO)
    205      * 
    206      * @param content
    207      *            内容
    208      * @param imgPath
    209      *            LOGO地址
    210      * @param output
    211      *            输出流
    212      * @param needCompress
    213      *            是否压缩LOGO
    214      * @throws Exception
    215      */
    216     public static void encode(String content, String imgPath,
    217             OutputStream output, boolean needCompress) throws Exception {
    218         BufferedImage image = QRCodeUtil.createImage(content, imgPath,
    219                 needCompress);
    220         ImageIO.write(image, FORMAT_NAME, output);
    221     }
    222 
    223     /**
    224      * 生成二维码
    225      * 
    226      * @param content
    227      *            内容
    228      * @param output
    229      *            输出流
    230      * @throws Exception
    231      */
    232     public static void encode(String content, OutputStream output)
    233             throws Exception {
    234         QRCodeUtil.encode(content, null, output, false);
    235     }
    236 
    237     /**
    238      * 解析二维码
    239      * 
    240      * @param file
    241      *            二维码图片
    242      * @return
    243      * @throws Exception
    244      */
    245     public static String decode(File file) throws Exception {
    246         BufferedImage image;
    247         image = ImageIO.read(file);
    248         if (image == null) {
    249             return null;
    250         }
    251         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
    252                 image);
    253         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    254         Result result;
    255         Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
    256         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
    257         result = new MultiFormatReader().decode(bitmap, hints);
    258         String resultStr = result.getText();
    259         return resultStr;
    260     }
    261 
    262     /**
    263      * 解析二维码
    264      * 
    265      * @param path
    266      *            二维码图片地址
    267      * @return
    268      * @throws Exception
    269      */
    270     public static String decode(String path) throws Exception {
    271         return QRCodeUtil.decode(new File(path));
    272     }
    273 
    274     public static void main(String[] args) throws Exception {
    275         String text = "https://www.hao123.com/";
    276         QRCodeUtil.encode(text, "G:/新建文件夹/1/2.png", "G:/新建文件夹/1/", true);
    277     }
    278 }
     1 package a;
     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 /**
    继承 LuminanceSource 实现解析二维码
    */ 9 public class BufferedImageLuminanceSource extends LuminanceSource { 10 private final BufferedImage image; 11 private final int left; 12 private final int top; 13 14 public BufferedImageLuminanceSource(BufferedImage image) { 15 this(image, 0, 0, image.getWidth(), image.getHeight()); 16 } 17 18 public BufferedImageLuminanceSource(BufferedImage image, int left, int top, 19 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( 26 "Crop rectangle does not fit within image data."); 27 } 28 29 for (int y = top; y < top + height; y++) { 30 for (int x = left; x < left + width; x++) { 31 if ((image.getRGB(x, y) & 0xFF000000) == 0) { 32 image.setRGB(x, y, 0xFFFFFFFF); // = white 33 } 34 } 35 } 36 37 this.image = new BufferedImage(sourceWidth, sourceHeight, 38 BufferedImage.TYPE_BYTE_GRAY); 39 this.image.getGraphics().drawImage(image, 0, 0, null); 40 this.left = left; 41 this.top = top; 42 } 43 44 public byte[] getRow(int y, byte[] row) { 45 if (y < 0 || y >= getHeight()) { 46 throw new IllegalArgumentException( 47 "Requested row is outside the image: " + y); 48 } 49 int width = getWidth(); 50 if (row == null || row.length < width) { 51 row = new byte[width]; 52 } 53 image.getRaster().getDataElements(left, top + y, width, 1, row); 54 return row; 55 } 56 57 public byte[] getMatrix() { 58 int width = getWidth(); 59 int height = getHeight(); 60 int area = width * height; 61 byte[] matrix = new byte[area]; 62 image.getRaster().getDataElements(left, top, width, height, matrix); 63 return matrix; 64 } 65 66 public boolean isCropSupported() { 67 return true; 68 } 69 70 public LuminanceSource crop(int left, int top, int width, int height) { 71 return new BufferedImageLuminanceSource(image, this.left + left, 72 this.top + top, width, height); 73 } 74 75 public boolean isRotateSupported() { 76 return true; 77 } 78 79 public LuminanceSource rotateCounterClockwise() { 80 int sourceWidth = image.getWidth(); 81 int sourceHeight = image.getHeight(); 82 AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 83 0.0, sourceWidth); 84 BufferedImage rotatedImage = new BufferedImage(sourceHeight, 85 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 91 - (left + width), getHeight(), width); 92 } 93 }
  • 相关阅读:
    Annotation
    GIT的作用以及Versioncontrol为什么要用GIT
    Http协议
    人工智能的可怕与不可怕
    Makefile简易教程
    Node.js 学习笔记之一:学习规划 & 认知 Node.js
    《大教堂与集市》的启示 — 软件工程的另一种选择
    Git简易教程
    谈谈买书与读书
    clang编译器简介
  • 原文地址:https://www.cnblogs.com/HHR-SUN/p/8120098.html
Copyright © 2011-2022 走看看