生成带图片无白边的二维码

二维码

转载请注明出处:https://blog.csdn.net/u013173247/article/details/81748481

二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
上面都是百度百科复制的,知道咱们生成的是矩阵二维码就行。
本文是maven工程使用zxing 3.3.0的版本生成可自定义图片的二维码,并且可以去除二维码白边。(生成二维码有白边,或二维码内容多少改变有白边的同学请看这里)。

maven引入jar:

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.0</version>
</dependency>

如果不是maven工程,可以直接下载 jar包下载

准备工作做完了,开始正文。

package com.neusoft.saas.contactcentre.controller.qrCode;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeFactory {  

    public static String EncodeQRCODE(String contents, int width, int height,
            String iconImagePath, String codePath,String ImageName) 
                    throws IOException, WriterException{ 
        try{
            if(width == 0){
                width = 300; // 二维码图片宽度430
            }
            if(height == 0){
                height = 300; // 二维码图片高度430 
            }
            File testFile = new File(codePath);
            if(!testFile .exists()){
                testFile.mkdir();//创建目录
            }
            testFile = new File(codePath,ImageName);
            if(!testFile .exists()){
                testFile.createNewFile();//创建文件
            }
            String format = "png";// 二维码的图片格式png  

            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();  
             // 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)  
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
            // 内容所使用字符集编码  
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");     
//          hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值  
//          hints.put(EncodeHintType.MIN_SIZE, 200);//设置图片的最小值  
            hints.put(EncodeHintType.MARGIN, 0);   //设置白边 

            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容  
                    //编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,  
                    //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,  
                    //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //条形码的宽度  
                    height, //条形码的高度  
                    hints);//生成条形码时的一些配置,此项可选  

            // 生成二维码
            MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);
            return codePath+ImageName;
        } catch (IOException e) {
            System.err.println("图片读取异常 : "+e.getMessage());
        } catch (WriterException e) {
            System.err.println("图片输出异常 :"+e.getMessage());
        }
        return null;
    }    
    public static void main(String[] args) throws Exception {  
        try {  
            String contents = "https://blog.csdn.net/u013173247/article/details/41676495";
            String codeIconPath = "src/main/resources/view/src/static/images/QRCodeIconImg.png";
            String codePath =  System.getProperty("user.dir")+"/testQrcode/";
            String pngStr = new Date().getTime()+".png";
            String qrcodeImagePath = codePath + pngStr;
            EncodeQRCODE(contents,280, 280, codeIconPath, codePath,pngStr);  
            if(qrcodeImagePath != null){
                File file = new File(qrcodeImagePath);
                String base64 = ImageUtil.encodeImgageToBase64(file);
                base64 = base64.replaceAll("\r|\n", "");
//              if (!file.exists()) {
//                  System.out.println("删除文件失败:" + qrcodeImagePath + "刚生成的file不存在!");
//              } else {
//                  if (file.isFile()){
//                      file.delete();
//                  }
//              }
                System.out.println("base64");
                System.out.println(base64);
            }else{
                System.out.println("报错了!");
            }
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

生成的二维码如下

这里写图片描述

上图二维码有很大的白边,看下源码为什么有白边。从这行开始找

BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容  
                    //编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,  
                    //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,  
                    //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //条形码的宽度  
                    height, //条形码的高度  
                    hints);//生成条形码时的一些配置,此项可选  

往里跳

       case QR_CODE:
        writer = new QRCodeWriter();
        break;
      case CODE_39:
        writer = new Code39Writer();
        break;
      case CODE_93:
        writer = new Code93Writer();
        break;
      case CODE_128:
        writer = new Code128Writer();
        break;
      case ITF:
        writer = new ITFWriter();
        break;
      case PDF_417:
        writer = new PDF417Writer();
        break;
      case CODABAR:
        writer = new CodaBarWriter();
        break;
      case DATA_MATRIX:
        writer = new DataMatrixWriter();
        break;
      case AZTEC:
        writer = new AztecWriter();
        break;
      default:
        throw new IllegalArgumentException("No encoder available for format " + format);
    }
    return writer.encode(contents, format, width, height, hints);

writer.encode(contents, format, width, height, hints)继续往里找

ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
    int quietZone = QUIET_ZONE_SIZE;
    if (hints != null) {
      if (hints.containsKey(EncodeHintType.ERROR_CORRECTION)) {
        errorCorrectionLevel = ErrorCorrectionLevel.valueOf(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
      }
      if (hints.containsKey(EncodeHintType.MARGIN)) {
        quietZone = Integer.parseInt(hints.get(EncodeHintType.MARGIN).toString());
      }
    }

    QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
    return renderResult(code, width, height, quietZone);

QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);这行继续往里找

//  Choose the mask pattern and set to "qrCode".
    int dimension = version.getDimensionForVersion();
    ByteMatrix matrix = new ByteMatrix(dimension, dimension);
    int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
    qrCode.setMaskPattern(maskPattern);

    // Build the matrix and set it to "qrCode".
    MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
    qrCode.setMatrix(matrix);

注意!!!

int dimension = version.getDimensionForVersion();

往里找会发现

public int getDimensionForVersion() {
    return 17 + 4 * versionNumber;
  }

根据版本号计算出的值,本人的versionNumber值是10
dimension 值为57
main方法中要生成的是280
280/57=4余52
可以跳转生成的数据,比如此二维码可以跳转main方法中的值为228

问题来了:如果内容长度不固定,还想没有白边,怎么办?
接着往下看。

写一个去除白边的方法

public static BitMatrix deleteWhite(BitMatrix matrix){  
        int[] rec = matrix.getEnclosingRectangle();  
        int resWidth = rec[2];  
        int resHeight = rec[3];  
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);  
        resMatrix.clear();  
        for (int i = 0; i < resWidth; i++) {  
            for (int j = 0; j < resHeight; j++) { 
                if (matrix.get(i + rec[0], j + rec[1]))  
                    resMatrix.set(i, j);  
            }  
        }  
        return resMatrix;  
    }

在代码中调用

 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容  
                    //编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,  
                    //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,  
                    //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION  
                    BarcodeFormat.QR_CODE,  
                    width, //条形码的宽度  
                    height, //条形码的高度  
                    hints);//生成条形码时的一些配置,此项可选  

            // 生成二维码  
//          File outputFile = new File(codePath,new Date().getTime()+".png");//指定输出路径  
            bitMatrix = deleteWhite(bitMatrix);  
            MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);

生成的会是没有任何白边的二维码

问题又来了:如果我就想要固定大小白边的怎么办?

修改下去除白边方法的代码

public static BitMatrix deleteWhite(BitMatrix matrix){  
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 2;
        int resHeight = rec[3] + 2;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);  
        resMatrix.clear();  
        for (int i = 0; i < resWidth; i++) {  
            for (int j = 0; j < resHeight; j++) {  
                if (matrix.get(i + rec[0], j + rec[1]))  
                    resMatrix.set(i+1, j+1);  
            }  
        }  
        return resMatrix;  
    }

上面代码就是给二位码添加1的白边
完成。最后附上源码下载链接源码下载

转载请注明出处:https://blog.csdn.net/u013173247/article/details/81748481

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值