`

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

阅读更多

       二维码技术不是什么新技术了,但是这几天工作用到,然后才现学习现使用,使用的是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创建的。

代码可以从我的github中下载:https://github.com/hejiawang/QRCodeCreateAndScanTool

右下角能够下载。

欢迎指正

  • 大小: 18.7 KB
  • 大小: 31 KB
  • 大小: 17.4 KB
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics