zxing生成解析二维码以及二维码生成解析的一个Android应用程序

孤街醉人 提交于 2019-11-29 05:32:32

二维码技术不是什么新技术了,但是这几天工作用到,然后才现学习现使用,使用的是Google的ZXing,使用起来很简单,

我练习的两种方式,一种的简单的javase工程,一种是Android客户端生成解析二维码的demo,线面逐个介绍。

一、JavaSE生成解析二维码,就是建立一个JavaProject,然后导入jar包,我用的是maven,所以建立了一个简单的maven工程。


1、第一种形式,生成一个中间没有logo的二维码,并解析,写好之后,直接说哪个junit测试,就能生成解析二维码了

package com.wang.qr.code;  
  
import java.awt.image.BufferedImage;  
import java.io.File;  
import java.io.IOException;  
import java.nio.file.FileSystems;  
import java.nio.file.Path;  
import java.util.HashMap;  
import java.util.Map;  
  
import javax.imageio.ImageIO;  
  
import org.junit.Test;  
  
import com.alibaba.fastjson.JSONObject;  
import com.google.zxing.BarcodeFormat;  
import com.google.zxing.Binarizer;  
import com.google.zxing.BinaryBitmap;  
import com.google.zxing.DecodeHintType;  
import com.google.zxing.EncodeHintType;  
import com.google.zxing.LuminanceSource;  
import com.google.zxing.MultiFormatReader;  
import com.google.zxing.MultiFormatWriter;  
import com.google.zxing.NotFoundException;  
import com.google.zxing.Result;  
import com.google.zxing.WriterException;  
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;  
import com.google.zxing.client.j2se.MatrixToImageWriter;  
import com.google.zxing.common.BitMatrix;  
import com.google.zxing.common.HybridBinarizer;  
  
/** 
 * 生成没有logo的二维码</br> 有多个信息json 
 *  
 * @author wang 
 *  
 */  
public class QRCodeTest1 {  
  
    /** 
     * 生成二维码</br> 
     *  
     * 二维码中的内容是json数据 
     *  
     * @throws WriterException 
     * @throws IOException 
     */  
    @Test  
    public void testEncode() throws WriterException, IOException {  
  
        /* 
         * 把生成的二维码放到此目录下 
         */  
        String filePath = "E://";  
  
        /* 
         * 生成的二维码名称 
         */  
        String fileName = "zxing.png";  
  
        JSONObject json = new JSONObject();  
        json.put("zxing", "https://github.com/zxing/zxing/tree/zxing-3.0.0/javase/src/main/java/com/google/zxing");  
        json.put("author", "shihy");  
  
        /* 
         * 二维码中的内容 
         */  
        String content = json.toJSONString();// 内容  
  
        int width = 200; // 图像宽度  
        int height = 200; // 图像高度  
        String format = "png";// 图像类型  
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();  
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);// 生成矩阵  
        Path path = FileSystems.getDefault().getPath(filePath, fileName);  
        MatrixToImageWriter.writeToPath(bitMatrix, format, path);// 输出图像  
        System.out.println("输出成功.");  
    }  
  
    /** 
     * 解析二维码</br> 二维码中的内容是json数据 
     */  
    @Test  
    public void testDecode() {  
  
        /* 
         * 要解析的二维码 
         */  
        String filePath = "E://zxing.png";  
  
        BufferedImage image;  
        try {  
            image = ImageIO.read(new File(filePath));  
            LuminanceSource source = new BufferedImageLuminanceSource(image);  
            Binarizer binarizer = new HybridBinarizer(source);  
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();  
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");  
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码  
              
            /* 
             * 得到二维码中的字符串内容 
             */  
            //String context = result.getText();  
              
            JSONObject content = JSONObject.parseObject(result.getText());  
            System.out.println("图片中内容:  ");  
            System.out.println("author: " + content.getString("author"));  
            System.out.println("zxing:  " + content.getString("zxing"));  
            System.out.println("图片中格式:  ");  
            System.out.println("encode: " + result.getBarcodeFormat());  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (NotFoundException e) {  
            e.printStackTrace();  
        }  
    }  
}

2、第二种形式,生成有logo的二维码,工具类如下

package com.wang.qr.code.utils;  
  
import java.awt.Graphics2D;  
import java.awt.Image;  
import java.awt.image.BufferedImage;  
import java.io.BufferedReader;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.util.Hashtable;  
  
import javax.imageio.ImageIO;  
  
import com.google.zxing.BarcodeFormat;  
import com.google.zxing.EncodeHintType;  
import com.google.zxing.MultiFormatWriter;  
import com.google.zxing.client.j2se.MatrixToImageWriter;  
import com.google.zxing.common.BitMatrix;  
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  
/** 
 * 生成普通二维码和生成带logo的二维码 
 *  
 * @author wang 
 *  
 */  
public class QRCodeTestUtil3 {  
  
    private static final int BLACK = 0xFF000000;  
    private static final int WHITE = 0xFFFFFFFF;  
  
    /** 
     * 生成普通没有logo的二维码 
     *  
     * @param filePath 
     *            文本文件路径,该文件中的内容是生成二维码图片中的内容(文本需以UTF-8) 
     * @param imgFormate 
     *            指定生成的二维码图片的后缀名 
     * @param width 
     *            指定生成的二维码图片的宽度 
     * @param height 
     *            指定生成的二维码图片的高度 
     */  
    public static void createTwoDimensionalCode(String filePath, String imgFormate, int width, int height) {  
        File file = new File(filePath);  
        StringBuffer contents = new StringBuffer("");  
        // 读取文本文件内容到 contents  
        try {  
            InputStream is = new FileInputStream(file);  
            InputStreamReader isr = new InputStreamReader(is);  
            BufferedReader br = new BufferedReader(isr);  
            try {  
                String temp = br.readLine();  
                while (temp != null) {  
                    contents.append(temp + "\r\n");  
                    temp = br.readLine();  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
        // 得到图片该存放路径  
        String imgPath = file.getParent();  
        // 得到文件该设置的名字  
        String imgName = file.getName();  
        int endIndex = imgName.lastIndexOf(".");  
        imgName = imgName.substring(0, endIndex);  
  
        File imageFile = new File(imgPath, imgName + "." + imgFormate);  
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();  
        // 指定纠错等级  
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  
        // 指定编码格式  
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
        try {  
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents.toString(), BarcodeFormat.QR_CODE, width,  
                    height, hints);  
            MatrixToImageWriter.writeToPath(bitMatrix, imgFormate, imageFile.toPath());  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    /** 
     * 生成带logo的二维码图片 
     *  
     * @param url 
     *            要生成二维码的url 
     * @param imgPath 
     *            二维码生成的绝对路径 
     * @param logoPath 
     *            二维码中间logo绝对地址 
     * @throws Exception 
     */  
    public static void get2CodeImage(String url, String imgPath, String logoPath) throws Exception {  
        String format = "png";  
        Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
        BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 300, 300, hints);  
        File qrcodeFile = new File(imgPath);  
        writeToFile(bitMatrix, format, qrcodeFile, logoPath);  
    }  
  
    /** 
     *  
     * @param matrix 
     *            二维码矩阵相关 
     * @param format 
     *            二维码图片格式 
     * @param file 
     *            二维码图片文件 
     * @param logoPath 
     *            logo路径 
     * @throws IOException 
     */  
    private static void writeToFile(BitMatrix matrix, String format, File file, String logoPath) throws IOException {  
        BufferedImage image = toBufferedImage(matrix);  
        Graphics2D gs = image.createGraphics();  
  
        // 载入logo  
        Image img = ImageIO.read(new File(logoPath));  
        gs.drawImage(img, 125, 125, null);  
        gs.dispose();  
        img.flush();  
        if (!ImageIO.write(image, format, file)) {  
            throw new IOException("Could not write an image of format " + format + " to " + file);  
        }  
    }  
  
    private static BufferedImage toBufferedImage(BitMatrix matrix) {  
        int width = matrix.getWidth();  
        int height = matrix.getHeight();  
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  
        for (int x = 0; x < width; x++) {  
            for (int y = 0; y < height; y++) {  
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);  
            }  
        }  
        return image;  
    }  
}

测试类:

package com.wang.qr.code;  
  
import org.junit.Test;  
  
import com.wang.qr.code.utils.QRCodeTestUtil3;  
  
/** 
 * @author wang 
 *  
 */  
public class QRCodeTest3 {  
  
    @Test  
    public void createNoLogoQRCode() {  
        QRCodeTestUtil3.createTwoDimensionalCode("E://test.txt", "png", 200, 200);  
    }  
  
    @Test  
    public void createHaveLogoQRCode() {  
        try {  
            QRCodeTestUtil3.get2CodeImage("https://shop100133013.taobao.com/shop/view_shop.htm?spm=a1z0k.7386009.1997989141.d4915209.abFEJh&shop_id=100133013", "E://havalogoQRCode.png", "E://logo.png");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

效果图:(一张有用的二维码,不信可以用微信扫扫哦。。。)

在联系的时候,我是用的maven工程,附上maven工程的pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
  
    <groupId>QRCodeTest</groupId>  
    <artifactId>QRCodeTest</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <packaging>jar</packaging>  
  
    <name>QRCodeTest</name>  
    <url>http://maven.apache.org</url>  
  
    <properties>  
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    </properties>  
  
    <dependencies>  
        <dependency>  
            <groupId>junit</groupId>  
            <artifactId>junit</artifactId>  
            <version>4.10</version>  
            <scope>test</scope>  
        </dependency>  
          
        <dependency>  
            <groupId>com.google.zxing</groupId>  
            <artifactId>core</artifactId>  
            <version>3.2.1</version>  
        </dependency>  
        <dependency>  
            <groupId>com.google.zxing</groupId>  
            <artifactId>javase</artifactId>  
            <version>3.2.1</version>  
        </dependency>  
        <dependency>  
            <groupId>com.alibaba</groupId>  
            <artifactId>fastjson</artifactId>  
            <version>1.2.7</version>  
        </dependency>  
          
          
    </dependencies>  
</project>

二、第二个练习的是写了一个Android的应用程序,能够根据填写内容,和是否选择二维码logo,生成一个二维码;能够像微信一样扫描二维码(在网上找到的demo代码直接用的),

Android上生成二维码与javase生成二维码的核心代码原理一样,都是zxing,但是有不一样的地方,javase生成二维码后,能够直 接在本地保存二维码文件。Android应用程序这样的话就不要友好了,我们应该先将二维码生成bitmap的形式,然后显示在imageView上面, 由使用者选择是否保存二维码,就像下面的界面一样,

这样的话,生成二维码的代码就不一样了。下面是在Android中生成二维码bitmap的代码:

package com.wang.qrcodecreateandscantool.util;  
  
import android.graphics.Bitmap;  
import android.graphics.Canvas;  
  
import com.google.zxing.BarcodeFormat;  
import com.google.zxing.EncodeHintType;  
import com.google.zxing.MultiFormatWriter;  
import com.google.zxing.common.BitMatrix;  
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  
import java.util.Hashtable;  
  
/** 
 * 生成二维码的工具类 
 * <p/> 
 * Created by wang on 2015/11/12. 
 */  
public class QRCodeCreateUtil {  
  
    /** 
     * 生成没有logo的二维码Bitmap 
     * 
     * @param context   二维码内容 
     * @param widthPix  二维码宽度 
     * @param heightPix 二维码高度 
     * @return Bitmap 
     */  
    public static Bitmap createNoLogoQRCode(String context, int widthPix, int heightPix) {  
        Bitmap bitmap = null;  
        try {  
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();  
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
            BitMatrix bitMatrix = new MultiFormatWriter().encode(context, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);  
            int[] pixels = new int[widthPix * heightPix];  
            for (int y = 0; y < heightPix; y++) {  
                for (int x = 0; x < widthPix; x++) {  
                    if (bitMatrix.get(x, y)) {  
                        pixels[y * widthPix + x] = 0xff000000;  
                    } else {  
                        pixels[y * widthPix + x] = 0xffffffff;  
                    }  
                }  
            }  
            bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);  
            bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return bitmap;  
    }  
  
    /** 
     * 生成有logo的二维码Bitmap 
     * 
     * @param context   二维码内容 
     * @param widthPix  二维码宽度 
     * @param heightPix 二维码高度 
     * @param logo      二维码logo的bitmap 
     * @return Bitmap 
     */  
    public static Bitmap createHaveLogoQRCode(String context, int widthPix, int heightPix, Bitmap logo) {  
  
        Bitmap haveLogoQRCodeBitmap = null;  
        Bitmap noLogoQRCodeBitmap = createNoLogoQRCode(context, widthPix, heightPix);  
        haveLogoQRCodeBitmap = addLogo(noLogoQRCodeBitmap, logo);  
        return haveLogoQRCodeBitmap;  
    }  
  
  
    /** 
     * 向原来的bitmap上面添加一个bitmap 
     * 
     * @param src  原始Bitmap 
     * @param logo 添加的Bitmap 
     * @return Bitmap 
     */  
    private static Bitmap addLogo(Bitmap src, Bitmap logo) {  
        if (src == null) {  
            return null;  
        }  
        if (logo == null) {  
            return src;  
        }  
        int srcWidth = src.getWidth();  
        int srcHeight = src.getHeight();  
        int logoWidth = logo.getWidth();  
        int logoHeight = logo.getHeight();  
        if (srcWidth == 0 || srcHeight == 0) {  
            return null;  
        }  
        if (logoWidth == 0 || logoHeight == 0) {  
            return src;  
        }  
        float scaleFactor = srcWidth * 1.0f / 8 / logoWidth;  
        Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);  
        try {  
            Canvas canvas = new Canvas(bitmap);  
            canvas.drawBitmap(src, 0, 0, null);  
            canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);  
            canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);  
  
            canvas.save(Canvas.ALL_SAVE_FLAG);  
            canvas.restore();  
        } catch (Exception e) {  
            bitmap = null;  
            e.getStackTrace();  
        }  
        return bitmap;  
    }  
}

相信有点Android基础的猿们都会使用上面的代码了,就不给使用代码了。

这个Android应用程序还能够像微信一样扫描二维码,就行下面一样:


这个功能是抄的,在网上找的示例代码,一点没改直接用了。。。扫描之后,能够对二维码的内容进行解析,显示在一个界面上。

这个Android应用程序是用Android studio创建的。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!