Java实现二维码技术探讨。

Java生成二维码方法有三种:

1: 使用SwetakeQRCode在Java项目中生成二维码

http://swetake.com/qr/ 下载地址

或着http://sourceforge.jp/projects/qrcode/downloads/28391/qrcode.zip

这个是日本人写的,生成的是我们常见的方形的二维码

能够用中文 如:5677777ghjjjjj

2: 使用BarCode4j生成条形码和二维码

BarCode4j网址:http://sourceforge.net/projects/barcode4j/

barcode4j是使用datamatrix的二维码生成算法,为支持qr的算法

datamatrix是欧美的标准。qr为日本的标准,

barcode4j一般生成出来是长方形的

如:88777alec000yan

这个博客这方面说的挺清楚的:

http://baijinshan.iteye.com/blog/1004554

3、如今具体介绍第三种也是经常使用的方式:利用Zxing生成二维码

Zxing是Google提供的关于条码(一维码、二维码)的解析工具,提供了二维码的生成与解析的方法,如今我简介一下使用Java利用Zxing生成与解析二维码。

第一步:将Zxing-core.jar 包增加项目中。

第二步 加入下面三个Java文件,三个文件功能例如以下:

MatrixToImageWriter.java  生成二维码图片。

BufferedImageLuminanceSource.java   解析二维码图片。

BarcodeFactory.java  生成带头像的二维码。

MatrixToImageWriter.java

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.awt.image.BufferedImage;

public final class MatrixToImageWriter {

	private static final int BLACK = 0xFF000000;
	private static final int WHITE = 0xFFFFFFFF;

	private MatrixToImageWriter() {
	}

	public 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;
	}

	public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		if (!ImageIO.write(image, format, file)) {
			throw new IOException("Could not write an image of format " + format + " to " + file);
		}
	}

	public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		if (!ImageIO.write(image, format, stream)) {
			throw new IOException("Could not write an image of format " + format);
		}
	}

	public static void main(String[] args) throws Exception {
		String text = "二维码内容,能够是链接也能够是文本";
		int width = 300;
		int height = 300;
		Hashtable hints = new Hashtable();
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//内容所使用编码
		BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);

		File outputFile = new File("E:/qrtest/生成普通二维码.jpg");
		//File.separator
		String format = "jpg";//二维码的图片格式
		MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);

	}
}

BufferedImageLuminanceSource.java

import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

public final class BufferedImageLuminanceSource extends LuminanceSource {

	private final BufferedImage image;
	private final int left;
	private final int top;

	public BufferedImageLuminanceSource(BufferedImage image) {
		this(image, 0, 0, image.getWidth(), image.getHeight());
	}

	public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
		super(width, height);

		int sourceWidth = image.getWidth();
		int sourceHeight = image.getHeight();
		if (left + width > sourceWidth || top + height > sourceHeight) {
			throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
		}

		for (int y = top; y < top + height; y++) {
			for (int x = left; x < left + width; x++) {
				if ((image.getRGB(x, y) & 0xFF000000) == 0) {
					image.setRGB(x, y, 0xFFFFFFFF); // = white
				}
			}
		}

		this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
		this.image.getGraphics().drawImage(image, 0, 0, null);
		this.left = left;
		this.top = top;
	}

	@Override
	public byte[] getRow(int y, byte[] row) {
		if (y < 0 || y >= getHeight()) {
			throw new IllegalArgumentException("Requested row is outside the image: " + y);
		}
		int width = getWidth();
		if (row == null || row.length < width) {
			row = new byte[width];
		}
		image.getRaster().getDataElements(left, top + y, width, 1, row);
		return row;
	}

	@Override
	public byte[] getMatrix() {
		int width = getWidth();
		int height = getHeight();
		int area = width * height;
		byte[] matrix = new byte[area];
		image.getRaster().getDataElements(left, top, width, height, matrix);
		return matrix;
	}

	@Override
	public boolean isCropSupported() {
		return true;
	}

	@Override
	public LuminanceSource crop(int left, int top, int width, int height) {
		return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
	}

	@Override
	public boolean isRotateSupported() {
		return true;
	}

	@Override
	public LuminanceSource rotateCounterClockwise() {

		int sourceWidth = image.getWidth();
		int sourceHeight = image.getHeight();

		AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);

		BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);

		Graphics2D g = rotatedImage.createGraphics();
		g.drawImage(image, transform, null);
		g.dispose();

		int width = getWidth();
		return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
	}

	public static void main(String[] args) {
		//解析二维码
		try {
			MultiFormatReader formatReader = new MultiFormatReader();
			String filePath = "E:/qrtest/生成普通二维码.jpg";
			File file = new File(filePath);
			BufferedImage image = ImageIO.read(file);
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			Binarizer binarizer = new HybridBinarizer(source);
			BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

			Map hints = new HashMap();
			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
			Result result = formatReader.decode(binaryBitmap, hints);

			System.out.println("result = " + result.toString());
			System.out.println("resultFormat = " + result.getBarcodeFormat());
			System.out.println("resultText = " + result.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

BarcodeFactory.java

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.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

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 BarcodeFactory {
	// 图片宽度的一般
	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;

	// 二维码写码器
	private static MultiFormatWriter mutiWriter = new MultiFormatWriter();

	/**
	 * 将srcImagePath嵌入到destImagePath
	 */
	public static void encode(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();
		}
	}

	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, "utf-8");
		hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 生成二维码
		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;
	}

	/**
	 * 把传入的原始图像按高度和宽度进行缩放。生成符合要求的图标
	 *
	 * @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;
	}

	public static void main(String[] args) {
		//src.jpg为头像文件
		BarcodeFactory.encode("http://www.baidu.com", 300, 300, "E:/qrtest/src.jpg","E:/qrtest/生成带头像的二维码.jpg");
	}
}
				
时间: 2024-08-13 15:27:50

Java实现二维码技术探讨。的相关文章

java生成二维码技术

代码来源潭州免费视频教程 需要Qrcode_swetake.jar类库,jquery.js 后台新建EcardServlet.java,修改web.xml的servlet映射 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //处理字符编码 request.setCharacterEncoding("utf-8&q

java生成二维码/java解析二维码

二维码的优缺点 优点:1. 高密度编码,信息容量大:2.编码范围广:3.容错能力强:4.译码可靠性高:5.可引入加密措施:6.成本低,易制作,持久耐用. 缺点:1.二维码技术成为手机病毒.钓鱼网站传播的新渠道:2.信息容易泄露. 三大国际标准 1.PDF417:不支持中文: 2.DM:专利未公开,需要支付专利费用: 3.QR Code:专利公开,支持中文. 其中,QR Code具有识读速度快.数据密度大.占用空间小的优势. 纠错能力 L级:约可纠错7%的数据码字 M级:约可纠错15%的数据码字

java 生成 二维码 和jquery 生成二维码

生成二维码 Java 生成二维码: 思路为拿到jar 包知道里面的方法使用 Step one : 在https://github.com/zxing中下载(点击网页中名为 zxing 的a标签,跳转到源码页面,点击release 查看所有发布的源码,下载zip压缩文件 Step two:  解压文件后打开文件夹,将core包和javase包 中的com包拷贝到一java项目src目录下.右键导出 jar file  得到一个二维码开发的jar包 Step three: 进行二维码制作 impor

java实现二维码

说起二维码,微信好像最先启用,随后各类二维码就开始流行起来了.那什么是二维码呢. 1.什么是二维码?百度一下即可 http://baike.baidu.com/view/132241.htm?fr=aladdin 2.java开发二维码? 2.1:首先导入:此包 下载地址:http://pan.baidu.com/s/1jGJwPwU 2.2:java类 1 import java.awt.image.BufferedImage; 2 3 /** 4 * Encapsulates custom

Java制作二维码代码,中间带logo图片,可设置logo大小

public static int createQRCode(String content, String imgPath,String logo) { try { Qrcode qrcodeHandler = new Qrcode(); qrcodeHandler.setQrcodeErrorCorrect('M'); qrcodeHandler.setQrcodeEncodeMode('B'); qrcodeHandler.setQrcodeVersion(7); // System.out

JAVA商家二维码系统

每天记录学习,每天会有好心情.*^_^* 在学习基于JAVA商家二维码生成与解析系统项目的时候,方便日后能及时查阅,在本平台中记录一下基于JAVA商家二维码生成与解析系统的开发流程.在学习时候的选用了SSM(MYECLIPSE),这个框架不论是学习还是使用都非常方便,简单易上手.是我们学习编程可以重点学习的一个框架,我在开发基于JAVA商家二维码生成与解析系统项目的时候选用了MYECLIPSE来搭建SSM(MYECLIPSE)框架,最终将基于JAVA商家二维码生成与解析系统项目开发为了一个 后台

java实现二维码生成的几个方法

1: 使用SwetakeQRCode在Java项目中生成二维码 http://swetake.com/qr/ 下载地址 或着http://sourceforge.jp/projects/qrcode/downloads/28391/qrcode.zip 这个是日本人写的,生成的是我们常见的方形的二维码 可以用中文 如:5677777ghjjjjj 2: 使用BarCode4j生成条形码和二维码 BarCode4j网址:http://sourceforge.net/projects/barcode

java创建二维码与解析二维码

二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”.“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集:每个字符占有一定的宽度:具有一定的校验功能等.同时还具有对不同行的信息自动识别功能.及处理图形旋转变化点.

Java实现二维码QRCode的编码和解码

涉及到的一些主要类库,方便大家下载: 编码lib:Qrcode_swetake.jar   (官网介绍-- http://www.swetake.com/qr/index-e.html) 解码lib:qrcode.jar                 (官网介绍-- http://sourceforge.jp/projects/qrcode/) [一].编码: Java代码QRCodeEncoderHandler.java package michael.qrcode; import java