zoukankan      html  css  js  c++  java
  • Java语言实现二维码的生成

    众所周知,现在生活中二维码已经是无处不见。走在街道上,随处可见广告标语旁有二维码,手机上QQ,微信加个好友都能通过二维码的方式,我不知道是什么时候兴起的二维码浪潮,但是我知道,这在我小时候可是见不到的。小小的一个方形图片,却能存储着大量的信息,是不是不可思议。当然路边的二维码希望大家还是不要贪小便宜,随便扫二维码很可能给你手机内置了病毒,导致个人信息的泄露,切记切记!

    话不多说,直接上代码。

    生成带logo的二维码代码:

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

    分别保存在两个java类文件中,然后打成jar包,直接调用包中的createCode方法即可,参数别分为二维码内容,图片路径,存放地址,图片是否需要压缩。

  • 相关阅读:
    侧方停车 成功50% 一把进不去 出去二把进
    在Windows上使用 Python 安装+ win10启用长路径
    无锡 苏州 上海 古镇 汇总20200129
    win10家庭版升级 到win10企业版
    WPS Office 2019 v11.8.2.8053地方企业版 2016 v10.8.2.6948
    WPS2019党政机关单位版(无广告困扰)
    自用Chrome插件推荐【附教程及下载】
    转载 https://www.cnblogs.com/bobo-pcb/p/11708459.html
    HDU1302_Snail【模拟题】【水题】
    how to add Javascript and CSS in page layout with sharepoint 2013
  • 原文地址:https://www.cnblogs.com/timePasser-leoli/p/7345823.html
Copyright © 2011-2022 走看看