基于zxing生成与解析二维码、条形码

     基于zxing(https://github.com/zxing/zxing)与maven,针对二维码(包括带图片的二维码)、条形码进行了简单的封装,以便在项目中更好的利用。

    ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android

     关于二维码的生成细节与原理,请参考:http://coolshell.cn/articles/10590.html

package com.qrcode;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
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.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;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class PRUtil {
	// 图片宽度的一般
	private static final int IMAGE_WIDTH = 80;
	private static final int IMAGE_HEIGHT = 80;
	private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
	private static final int FRAME_WIDTH = 2;

	/**
	 * 生成普通二维码
	 *
	 * @param contents
	 * @param width
	 * @param height
	 * @param imgPath
	 */
	public static void encodePR(String contents, int width, int height, String imgPath) {
		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
		// 指定纠错等级
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
		// 指定编码格式
		hints.put(EncodeHintType.CHARACTER_SET, "GBK");
		try {
			BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
					BarcodeFormat.QR_CODE, width, height, hints);
			MatrixToImageWriter.writeToStream(bitMatrix, "jpg",
					new FileOutputStream(imgPath));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成带图片的二维码
	 *
	 * @param content
	 * @param width
	 * @param height
	 * @param srcImagePath
	 * @param destImagePath
	 */
	public static void encodePR(String content, int width, int height,
			String srcImagePath, String destImagePath) {
		try {
			ImageIO.write(genBarcode(content, width, height, srcImagePath),
					"jpg", new File(destImagePath));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (WriterException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 针对二维码进行解析
	 *
	 * @param imgPath
	 * @return
	 */
	public static String decodePR(String imgPath) {
		BufferedImage image = null;
		Result result = null;
		try {
			image = ImageIO.read(new File(imgPath));
			if (image == null) {
				System.out.println("the decode image may be not exists.");
			}
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

			Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
			hints.put(DecodeHintType.CHARACTER_SET, "GBK");

			result = new MultiFormatReader().decode(bitmap, hints);
			return result.getText();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 创建条形码
	 *
	 * @param contents
	 * @param width
	 * @param height
	 * @param imgPath
	 */
	public static void encodeBar(String contents, int width, int height, String imgPath) {
		// 条形码的最小宽度
		int codeWidth = 98;
		codeWidth = Math.max(codeWidth, width);
		try {
			BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
					BarcodeFormat.EAN_13, codeWidth, height, null);

			MatrixToImageWriter.writeToStream(bitMatrix, "png",
					new FileOutputStream(imgPath));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 针对条形码进行解析
	 *
	 * @param imgPath
	 * @return
	 */
	public static String decodeBar(String imgPath) {
		BufferedImage image = null;
		Result result = null;
		try {
			image = ImageIO.read(new File(imgPath));
			if (image == null) {
				System.out.println("the decode image may be not exit.");
			}
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

			result = new MultiFormatReader().decode(bitmap, null);
			return result.getText();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
	 *
	 * @param srcImageFile 源文件地址
	 * @param height 目标高度
	 * @param width 目标宽度
	 * @param hasFiller 比例不对时是否需要补白:true为补白; false为不补白;
	 * @throws IOException
	 */
	private static BufferedImage scale(String srcImageFile, int height, int width,
			boolean hasFiller) throws IOException {
		double ratio = 0.0; // 缩放比例
		File file = new File(srcImageFile);
		BufferedImage srcImage = ImageIO.read(file);
		Image destImage = srcImage.getScaledInstance(width, height,
				BufferedImage.SCALE_SMOOTH);
		// 计算比例
		if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
			if (srcImage.getHeight() > srcImage.getWidth()) {
				ratio = (new Integer(height)).doubleValue()
						/ srcImage.getHeight();
			} else {
				ratio = (new Integer(width)).doubleValue()
						/ srcImage.getWidth();
			}
			AffineTransformOp op = new AffineTransformOp(
					AffineTransform.getScaleInstance(ratio, ratio), null);
			destImage = op.filter(srcImage, null);
		}
		if (hasFiller) {// 补白
			BufferedImage image = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D graphic = image.createGraphics();
			graphic.setColor(Color.white);
			graphic.fillRect(0, 0, width, height);
			if (width == destImage.getWidth(null))
				graphic.drawImage(destImage, 0,
						(height - destImage.getHeight(null)) / 2,
						destImage.getWidth(null), destImage.getHeight(null),
						Color.white, null);
			else
				graphic.drawImage(destImage,
						(width - destImage.getWidth(null)) / 2, 0,
						destImage.getWidth(null), destImage.getHeight(null),
						Color.white, null);
			graphic.dispose();
			destImage = image;
		}
		return (BufferedImage) destImage;
	}

	/**
	 * 产生带有图片的二维码缓冲图像
	 * @param content
	 * @param width
	 * @param height
	 * @param srcImagePath
	 * @return
	 * @throws WriterException
	 * @throws IOException
	 */
	private static BufferedImage genBarcode(String content, int width, int height,
			String srcImagePath) throws WriterException, IOException {
		// 读取源图像
		BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH,
				IMAGE_HEIGHT, true);
		int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
		for (int i = 0; i < scaleImage.getWidth(); i++) {
			for (int j = 0; j < scaleImage.getHeight(); j++) {
				srcPixels[i][j] = scaleImage.getRGB(i, j);
			}
		}

		Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
		hint.put(EncodeHintType.CHARACTER_SET, "GBK");
		hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 生成二维码
		MultiFormatWriter mutiWriter = new MultiFormatWriter();
		BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE,
				width, height, hint);

		// 二维矩阵转为一维像素数组
		int halfW = matrix.getWidth() / 2;
		int halfH = matrix.getHeight() / 2;
		int[] pixels = new int[width * height];

		for (int y = 0; y < matrix.getHeight(); y++) {
			for (int x = 0; x < matrix.getWidth(); x++) {
				// 读取图片
				if (x > halfW - IMAGE_HALF_WIDTH
						&& x < halfW + IMAGE_HALF_WIDTH
						&& y > halfH - IMAGE_HALF_WIDTH
						&& y < halfH + IMAGE_HALF_WIDTH) {
					pixels[y * width + x] = srcPixels[x - halfW
							+ IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
				}
				// 在图片四周形成边框
				else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
						&& x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
						&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
						+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
						|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
								&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
								&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
								+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
						|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
								&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
								&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
								- IMAGE_HALF_WIDTH + FRAME_WIDTH)
						|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
								&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
								&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
								+ IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
					pixels[y * width + x] = 0xfffffff;
				} else {
					// 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
					pixels[y * width + x] = matrix.get(x, y) ? 0xff000000
							: 0xfffffff;
				}
			}
		}

		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		image.getRaster().setDataElements(0, 0, width, height, pixels);

		return image;
	}

	public static void main(String[] args) {
		String imgPath = "d:/pr1.jpg";
		String contents = "你好,李四! welcome to zxing!"
				+ "\n李四的博客[http://my.oschina.net/cloudcoder]"
				+ "\nEmail[xxx@163.com]";
		// 普通二维码的生成与解析
		PRUtil.encodePR(contents, 300, 300, imgPath);
		System.out.println("生成二维码成功");
		System.out.println(PRUtil.decodePR(imgPath));

		// 带图片的二维的生成与解析
		imgPath = "d:/pr2.png";
		String srcPath = "d:/src.jpg";
		PRUtil.encodePR(contents, 300, 300, srcPath,imgPath);
		System.out.println("生成带图片的二维码成功");
		System.out.println(PRUtil.decodePR(imgPath));

		// 条形码的生成与解析
		imgPath = "d:/bar.png";
		PRUtil.encodeBar("6923450657713", 105, 50, imgPath);
		System.out.println("生成条形码成功");
		System.out.println(PRUtil.decodeBar(imgPath));
	}
}

pom.xml

<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>com.test</groupId>
	<artifactId>qrcode</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>qrcode</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.google.zxing</groupId>
			<artifactId>javase</artifactId>
			<version>3.0.0</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>
时间: 2024-11-03 17:19:01

基于zxing生成与解析二维码、条形码的相关文章

google zxing 生成和解析二维码

maven 项目pom.xml文件配置 <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&qu

.NET C#利用ZXing生成、识别二维码/条形码_C#教程

一.首先下载 ZXing.Net 地址是:http://zxingnet.codeplex.com/releases/view/117068 然后将对应版本 .dll 拖入项目中,再引用之. 主要是用 BarcodeWriter.BarcodeReader. 二.生成二维码 .NET 平台的代码始终要简单些. QrCodeEncodingOptions options = new QrCodeEncodingOptions(); options.CharacterSet = "UTF-8&quo

asp.net C#生成和解析二维码代码

  类库文件我们在文件最后面下载 [ThoughtWorks.QRCode.dll 就是类库] 使用时需要增加: using ThoughtWorks.QRCode.Codec; using ThoughtWorks.QRCode.Codec.Data; using ThoughtWorks.QRCode.Codec.Util; 主要源代码: 1.生成二维码 代码如下   QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); String enco

asp.net C#生成和解析二维码的实例代码_实用技巧

类库文件我们在文件最后面下载 [ThoughtWorks.QRCode.dll 就是类库] 使用时需要增加: 复制代码 代码如下: using ThoughtWorks.QRCode.Codec; using ThoughtWorks.QRCode.Codec.Data; using ThoughtWorks.QRCode.Codec.Util; 主要源代码: 1.生成二维码 复制代码 代码如下: QRCodeEncoder qrCodeEncoder = new QRCodeEncoder()

使用zxing工具包创建和解析二维码

关于二维码是什么,以及二维码是如何生成的,我也没有研究得很深入,就不多说了,以免误导大家.请参看: java 二维码原理以及用java实现的二维码的生成.解码 二维码的生成细节和原理 下面是一个可以生成和解析二维码的工具类,该类用到了zxing工具包,我通过Maven去下载的: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 <dependencies>     <!-- JavaSE包依赖于Core包,因此Core包不需要直接依赖了     <dependency

Android中二维码的生成方法(普通二维码、中心Logo 二维码、及扫描解析二维码)

首先声明我们通篇用的都是Google开源框架Zxing,要实现的功能有三个 ,生成普通二维码.生成带有中心图片Logo 的二维码,扫描解析二维码,直接上效果图吧 首先我们需要一个这样的 Zxing 的包类似于这样 接下来需要引入资源 1.drawable 中引入图片 navbar.png 2.layout中引入camera.xml.main.xml.qrcode_capture_page.xml 3.创建raw文件夹并添加beep.ogg 扫描声音 4.合并color.xml,copy ids.

几行代码搞定java生成解析二维码功能

最近公司要求扫描二维码和生成二维码的功能.而群里部分网友也提到了.我这里就写了一个demo,和大家分享.代码很简介,希望大家能够喜欢. 网友表示在网上搜索了很多,发现不是代码不全,就是jar不匹配. 我这里共享了一个zxing的2.2版本的例子,也提供了下载地址.实现代码如下: package com.herman.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcep

Android 二维码 生成和识别二维码 附源码下载_Android

今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS.Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解.今天主要是讲解如何使用ZXing库,生成和识别二维码.这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码. 1.ZXing库介绍 这里简单介绍一下ZXing库.ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口

Android 二维码 生成和识别二维码 附源码下载

今天讲一下目前移动领域很常用的技术--二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS.Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解.今天主要是讲解如何使用ZXing库,生成和识别二维码.这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码. 1.ZXing库介绍 这里简单介绍一下ZXing库.ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口