• Java代码生成内嵌图片的二维码 IT


    1.首先引入maven依赖: 

     1      <dependency>
     2             <groupId>com.google.zxing</groupId>
     3             <artifactId>core</artifactId>
     4             <optional>true</optional>
     5         </dependency>
     6         <dependency>
     7             <groupId>com.google.zxing</groupId>
     8             <artifactId>javase</artifactId>
     9             <optional>true</optional>
    10         </dependency> 

    2.直接上代码:

      1 package itfeng.util;
      2 
      3 import java.awt.Color;
      4 import java.awt.Graphics2D;
      5 import java.awt.Image;
      6 import java.awt.geom.AffineTransform;
      7 import java.awt.image.AffineTransformOp;
      8 import java.awt.image.BufferedImage;
      9 import java.io.File;
     10 import java.io.IOException;
     11 import java.io.OutputStream;
     12 import java.net.HttpURLConnection;
     13 import java.net.URL;
     14 import java.nio.file.Path;
     15 import java.util.HashMap;
     16 import java.util.Hashtable;
     17 
     18 import javax.imageio.ImageIO;
     19 
     20 import com.google.zxing.BarcodeFormat;
     21 import com.google.zxing.BinaryBitmap;
     22 import com.google.zxing.DecodeHintType;
     23 import com.google.zxing.EncodeHintType;
     24 import com.google.zxing.MultiFormatReader;
     25 import com.google.zxing.MultiFormatWriter;
     26 import com.google.zxing.Result;
     27 import com.google.zxing.WriterException;
     28 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
     29 import com.google.zxing.client.j2se.MatrixToImageWriter;
     30 import com.google.zxing.common.BitMatrix;
     31 import com.google.zxing.common.HybridBinarizer;
     32 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
     33 
     34 public class QRcodeUtil {
     35 
     36     //注意:图片的宽度和高度占比会影响生成的二维码内容是否解析成功
     37     private static final int IMAGE_WIDTH = 120;
     38 
     39     private static final int IMAGE_HEIGHT = 120;
     40 
     41     private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
     42 
     43     private static final int FRAME_WIDTH = 0;
     44 
     45     private static final String IMAGE_FORMAT = "jpg";
     46 
     47     //二维码外边距
     48     private static final int IMAGE_MARGIN = 0;
     49 
     50     private static final String CHARSET = "UTF-8";
     51 
     52     // 二维码写码器  
     53     private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
     54 
     55     public static void main(String[] args) throws Exception {
     56         encode("https://hanyu.baidu.com/s?wd=%E7%99%BD%E6%97%A5%E6%A2%A6", 300, 300, "D:/cow.jpg",
     57                 "D:/cow二维码.jpg");//"D:/jjsd.jpg"
     58         System.out.println("二维码生成完毕!");
     59         System.out.println(decode("D:/cow二维码.jpg"));
     60     }
     61 
     62     @SuppressWarnings({ "rawtypes", "unchecked" })
     63     public static String decode(File file) throws Exception {
     64         BufferedImage image;
     65         image = ImageIO.read(file);
     66         if (image == null) {
     67             return null;
     68         }
     69         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
     70         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
     71         Result result;
     72         Hashtable hints = new Hashtable();
     73         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
     74         result = new MultiFormatReader().decode(bitmap, hints);
     75         String resultStr = result.getText();
     76         return resultStr;
     77     }
     78 
     79     public static String decode(String path) throws Exception {
     80         return decode(new File(path));
     81     }
     82 
     83     /** 
     84      *  
     85      * @param content 
     86      *            二维码显示的文本 
     87      * @param width 
     88      *            二维码的宽度 
     89      * @param height 
     90      *            二维码的高度 
     91      * @param srcImagePath 
     92      *            中间嵌套的图片 
     93      * @param destImagePath 
     94      *            二维码生成的地址 
     95      */
     96     public static void encode(String content, int width, int height, String srcImagePath,
     97             String destImagePath) {
     98         try {
     99             if (null != srcImagePath) {
    100                 ImageIO.write(genBarcode(content, width, height, srcImagePath), IMAGE_FORMAT,
    101                         new File(destImagePath));
    102             } else {
    103                 // 定义二维码的参数
    104                 HashMap<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
    105                 // 定义字符集编码格式
    106                 hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    107                 // 纠错的等级 L > M > Q > H 纠错的能力越高可存储的越少,一般使用M
    108                 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
    109                 // 设置图片边距
    110                 hints.put(EncodeHintType.MARGIN, IMAGE_MARGIN);
    111                 BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,
    112                         width, height, hints);
    113                 Path file = new File(destImagePath).toPath();
    114                 MatrixToImageWriter.writeToPath(matrix, IMAGE_FORMAT, file);
    115             }
    116         } catch (IOException e) {
    117             e.printStackTrace();
    118         } catch (WriterException e) {
    119             e.printStackTrace();
    120         }
    121     }
    122 
    123     /**
    124      * 
    125      * @param content
    126      *             二维码显示的文本
    127      * @param width
    128      *             二维码的宽度
    129      * @param height
    130      *             二维码的高度
    131      * @param srcImagePath
    132      *             中间嵌套的路径
    133      * @param out
    134      *             输入到流中
    135      */
    136     public static void encode(String content, int width, int height, String srcImagePath,
    137             OutputStream out) {
    138         try {
    139             if (null != srcImagePath) {
    140                 ImageIO.write(genBarcode(content, width, height, srcImagePath), IMAGE_FORMAT, out);
    141             } else {
    142 
    143                 // 定义二维码的参数
    144                 HashMap<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
    145                 // 定义字符集编码格式
    146                 hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    147                 // 纠错的等级 L > M > Q > H 纠错的能力越高可存储的越少,一般使用M
    148                 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
    149                 // 设置图片边距
    150                 hints.put(EncodeHintType.MARGIN, IMAGE_MARGIN);
    151                 BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,
    152                         width, height, hints);
    153                 MatrixToImageWriter.writeToStream(matrix, IMAGE_FORMAT, out);
    154             }
    155         } catch (IOException e) {
    156             e.printStackTrace();
    157         } catch (WriterException e) {
    158             e.printStackTrace();
    159         }
    160     }
    161 
    162     /** 
    163      * 得到BufferedImage 
    164      *  
    165      * @param content 
    166      *            二维码显示的文本 
    167      * @param width 
    168      *            二维码的宽度 
    169      * @param height 
    170      *            二维码的高度 
    171      * @param srcImagePath 
    172      *            中间嵌套的图片 
    173      * @return 
    174      * @throws WriterException 
    175      * @throws IOException 
    176      */
    177     @SuppressWarnings({ "rawtypes", "unchecked" })
    178     private static BufferedImage genBarcode(String content, int width, int height,
    179             String srcImagePath) throws WriterException, IOException {
    180         // 读取源图像  
    181         BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true);
    182 
    183         int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
    184         for (int i = 0; i < scaleImage.getWidth(); i++) {
    185             for (int j = 0; j < scaleImage.getHeight(); j++) {
    186                 srcPixels[i][j] = scaleImage.getRGB(i, j);
    187             }
    188         }
    189         Hashtable hint = new Hashtable();
    190         hint.put(EncodeHintType.CHARACTER_SET, CHARSET);
    191         hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    192         hint.put(EncodeHintType.MARGIN, IMAGE_MARGIN);
    193         // 生成二维码  
    194         BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hint);
    195 
    196         // 二维矩阵转为一维像素数组  
    197         int halfW = matrix.getWidth() / 2;
    198         int halfH = matrix.getHeight() / 2;
    199         int[] pixels = new int[width * height];
    200 
    201         // System.out.println(matrix.getHeight());  
    202         for (int y = 0; y < matrix.getHeight(); y++) {
    203             for (int x = 0; x < matrix.getWidth(); x++) {
    204                 // 读取图片  
    205                 if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH
    206                         && y > halfH - IMAGE_HALF_WIDTH && y < halfH + IMAGE_HALF_WIDTH) {
    207                     pixels[y * width + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH
    208                             + IMAGE_HALF_WIDTH];
    209                 }
    210                 // 在图片四周形成边框  
    211                 else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
    212                         && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
    213                         && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
    214                         && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
    215                         || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
    216                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
    217                                 && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
    218                                 && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)
    219                         || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
    220                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
    221                                 && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH
    222                                 && y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH)
    223                         || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
    224                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
    225                                 && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH
    226                                 && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
    227                     pixels[y * width + x] = 0xfffffff;
    228                 } else {
    229                     // 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;  
    230                     pixels[y * width + x] = matrix.get(x, y) ? 0xff000000 : 0xfffffff;
    231                 }
    232             }
    233         }
    234 
    235         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    236         image.getRaster().setDataElements(0, 0, width, height, pixels);
    237 
    238         return image;
    239     }
    240 
    241     /** 
    242      * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标 
    243      *  
    244      * @param srcImageFile 
    245      *            源文件地址 
    246      * @param height 
    247      *            目标高度 
    248      * @param width 
    249      *            目标宽度 
    250      * @param hasFiller 
    251      *            比例不对时是否需要补白:true为补白; false为不补白; 
    252      * @throws IOException 
    253      */
    254     private static BufferedImage scale(String srcImageFile, int height, int width,
    255             boolean hasFiller) throws IOException {
    256         double ratio = 0.0; // 缩放比例  
    257 
    258         //        URL url = new URL(srcImageFile);
    259         //        HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
    260         //        httpUrl.connect();
    261 
    262         File file = new File(srcImageFile);
    263         BufferedImage srcImage = ImageIO.read(file);
    264         //        BufferedImage srcImage = ImageIO.read(httpUrl.getInputStream());
    265         Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
    266         // 计算比例  
    267         if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
    268             if (srcImage.getHeight() > srcImage.getWidth()) {
    269                 ratio = (new Integer(height)).doubleValue() / srcImage.getHeight();
    270             } else {
    271                 ratio = (new Integer(width)).doubleValue() / srcImage.getWidth();
    272             }
    273             AffineTransformOp op = new AffineTransformOp(
    274                     AffineTransform.getScaleInstance(ratio, ratio), null);
    275             destImage = op.filter(srcImage, null);
    276         }
    277         if (hasFiller) {// 补白  
    278             BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    279             Graphics2D graphic = image.createGraphics();
    280             graphic.setColor(Color.white);
    281             graphic.fillRect(0, 0, width, height);
    282             if (width == destImage.getWidth(null))
    283                 graphic.drawImage(destImage, 0, (height - destImage.getHeight(null)) / 2,
    284                         destImage.getWidth(null), destImage.getHeight(null), Color.white, null);
    285             else
    286                 graphic.drawImage(destImage, (width - destImage.getWidth(null)) / 2, 0,
    287                         destImage.getWidth(null), destImage.getHeight(null), Color.white, null);
    288             graphic.dispose();
    289             destImage = image;
    290         }
    291         return (BufferedImage) destImage;
    292     }
    293 }

    最终生成的二维码:

  • 相关阅读:
    Java MD5机密算法的使用
    JavaWeb学习总结-12 JSTL标签语言
    HTML5学习总结-09 拖放和手机触屏事件
    HTML5学习总结-08 应用缓存(Application Cache)
    HTML5学习总结-08 WebSocket 服务器推送
    软件架构阅读笔记06
    软件架构阅读笔记05
    软件架构阅读笔记04
    软件架构阅读笔记03
    软件架构阅读笔记02
  • 原文地址:https://www.cnblogs.com/itfeng813/p/14395315.html
Copyright © 2020-2023  润新知