QR Code二维条形码的生成和读取解析和摄像头的读取

星期日, 2010-02-28 | Author: Lee | JAVA-and-J2EE, php | 18,197 views

这两天不知道怎么对二维条形码感兴趣了,就找了下QR code的生成和读取方式,网上有开源的java项目,都是原来于日本的,分别是:

1.生成的QR code的网址是:http://swetake.com/qr/;
支持的原因版本还比较丰富,支持QRcode Perl的CGI和PHP脚本的版本,Ruby和java都有对应的支持类库等源代码,用起来还是很方便的;
2。读取和摄像头读取的是Open Source QR Code Library,官方网站为:http://qrcode.sourceforge.jp/ ,读取QR Code的所有代码,可以直接读取图片直接进行解析,也可以正常支持中文等,其中有个jmfexample就能实现通过摄像头读取QR Code;
把对应的java的代码,汇总打成了一个jar包,用起来也方便多了,jar包下载方式是:QRCode.jar

生成和读取的代码示例如下:
生成的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.liyz.qrcode.test;
 
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import com.swetake.util.Qrcode;
 
public class MakeQrcodeImages {
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		Qrcode qrcode=new Qrcode();
		qrcode.setQrcodeErrorCorrect('M');
		qrcode.setQrcodeEncodeMode('B');
		qrcode.setQrcodeVersion(7);
 
		String str="中国人nice5";
 
		byte[] bstr=str.getBytes("UTF-8");
		BufferedImage bi = new BufferedImage(139, 139, BufferedImage.TYPE_INT_RGB);    
		Graphics2D g = bi.createGraphics();    
 
        g.setBackground(Color.WHITE);    
        g.clearRect(0, 0, 139, 139);    
        g.setColor(Color.BLACK); 
 
        if (bstr.length>0 && bstr.length <123){    
            boolean[][] b = qrcode.calQrcode(bstr);    
            for (int i=0;i<b.length;i++){    
                for (int j=0;j<b.length;j++){    
                    if (b[j][i]) {    
                        g.fillRect(j*3+2,i*3+2,3,3);    
                    }    
                }    
 
            }    
        }    
        g.dispose();    
        bi.flush();    
        String FilePath="d:/QRCode.png";    
        File f = new File(FilePath);    
        ImageIO.write(bi, "png", f);    
        System.out.println("now doned!");  
	}
 
}

解码(读取图片)的测试对应代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.liyz.qrcode.test;
 
import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.util.ContentConverter;
import jp.sourceforge.qrcode.data.QRCodeImage;
import jp.sourceforge.qrcode.exception.DecodingFailedException;
 
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import jp.sourceforge.qrcode.util.DebugCanvas;
import jp.sourceforge.qrcode.util.DebugCanvasAdapter;
import java.net.URL;
 
// Smallest example of QRCode Decoder
 
public class QRCodeDecoderCUIExample {
 
	public static void main(String[] args) {
		args = new String[1];
		args[0] = "d:/QRCode.png";
 
		if (args.length < 1) {
			System.err.println("Usage: QRCodeDecoderCUIExample imageFilePath");
			System.exit(1);
		}
		int numSuccesses = 0;
		int numFailures = 0;
		QRCodeDecoder decoder = new QRCodeDecoder();
		long start = System.currentTimeMillis();
		for (String filename : args) {
			if (processDecode(filename, decoder)) {
				System.err.print("[Success] ");
				numSuccesses++;
			} else {
				System.err.print("[Failure] ");
				numFailures++;
			}
			System.err.println(filename);
		}
		long processTime = System.currentTimeMillis() - start;
		System.err.println("Processed " + args.length + " images in "
				+ processTime + "ms (" + processTime / args.length
				+ " images/sec)");
		System.err.println("OK: " + numSuccesses + " NG: " + numFailures);
	}
 
	/**
	 * 此处解析使用了utf-8的编码,生成的时候因为用了utf-8生成了中文,也都正常的读取和生成,感觉还是很不错的
	 * @param filename
	 * @param decoder
	 * @return
	 */
	static boolean processDecode(String filename, QRCodeDecoder decoder) {
		DebugCanvas canvas = new J2SECanvas();
		decoder.setCanvas(canvas);
		BufferedImage image = null;
		try {
			if (filename.startsWith("http://"))
				image = ImageIO.read(new URL(filename));
			else
				image = ImageIO.read(new File(filename));
			String decodedString = new String(decoder.decode(new J2SEImage(
					image)), "UTF-8");
			decodedString = ContentConverter.convert(decodedString);
			System.out.println(decodedString);
		} catch (IOException e) {
			canvas.println("Error: " + e.getMessage() + " " + filename);
			return false;
		} catch (DecodingFailedException dfe) {
			canvas.println("Error: " + dfe.getMessage());
			return false;
		} catch (Exception e) {
			canvas.println("Error: " + e.getMessage());
			return false;
		}
		return true;
	}
}
 
class J2SEImage implements QRCodeImage {
	BufferedImage image;
 
	public J2SEImage(BufferedImage source) {
		this.image = source;
	}
 
	public int getWidth() {
		return image.getWidth();
	}
 
	public int getHeight() {
		return image.getHeight();
	}
 
	public int getPixel(int x, int y) {
		return image.getRGB(x, y);
 
	}
}
 
class J2SECanvas extends DebugCanvasAdapter {
	public void println(String s) {
		// System.err.println(s);
	}
}

另计:在网上看到可以通过摄像头读取条形码的,因为自己的摄像头换了也没有去测试,估计应该也是没有问题的,把对应的方法贴出来吧:下面为引用,具体地址不记得了:
二维条形码比普通的条形码能保存更多的信息,已经应用到很多领域里面。例如手机电影票,就是一个嵌在彩信里面的二维码图像。南航也推出了网上办理登机牌业务,办理完成之后往手机发送一条包含二维码的彩信,到了机场就可以通过自助设备扫描二维码,打印登机牌。
然而,专业的二维码扫描设备价格十分昂贵,最便宜的都在1000元以上,到淘宝上搜搜就知道了。借助Java和一个开源的库,我们却可以通过普通的网络摄像头实现相同的效果,成本只需要几十块。
Open Source QR Code Library是一个开源的QR Code(二维条形码的一种)生成和读取的库,官方网站为:http://qrcode.sourceforge.jp/,里面包含了生成和读取QR Code的所有代码,其中有个jmfexample就能实现通过摄像头读取QR Code,经过本人尝试,几十块的普通摄像头效果已经不错了,一次读取几百字节都没问题。
使用这个库的步骤如下:
1、到其官方网站下载回来;
2、到sun的网站下载JMF包并安装;
3、插上摄像头,打开我的电脑,查看是否出现“USB视频设备”,然后打开,看摄像头工作是否正常
4、运行JMF里面的JMF Registry程序,点击“Detect Capture Devices”,查找视频设备,查找到之后会在左边的列表里出现“vfw:Microsoft WDM Image Capture (Win32):0”类似的设备,点击就会在右边出现其详细信息,我的摄像头是这样的:
Name = vfw:Microsoft WDM Image Capture (Win32):0

Locator = vfw://0

Output Formats—->

0. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 3

1. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=160,height=120] MaxDataLength = 38400 DataType = class [B yuvType = 32 StrideY = 320 StrideUV = 320 OffsetY = 0 OffsetU = 1 OffsetV = 3

2. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=176,height=144] MaxDataLength = 50688 DataType = class [B yuvType = 32 StrideY = 352 StrideUV = 352 OffsetY = 0 OffsetU = 1 OffsetV = 3

3. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=320,height=240] MaxDataLength = 153600 DataType = class [B yuvType = 32 StrideY = 640 StrideUV = 640 OffsetY = 0 OffsetU = 1 OffsetV = 3

4. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=352,height=288] MaxDataLength = 202752 DataType = class [B yuvType = 32 StrideY = 704 StrideUV = 704 OffsetY = 0 OffsetU = 1 OffsetV = 3

注意,其中Output Formats都是javax.media.format.YUVFormat,而QR Code Library里默认的设备不是这种格式的,所以需要对源码作一定的修改。

5、用Eclipse打开QR Code Library的源码,作出一些适当的修改:
如果摄像头是上面所说的只支持YUV格式,则需要修改jp.sourceforge.qrcode.example.jmf.camDataSource.java,把setMainSource函数里的
VideoFormat vidformat = new VideoFormat(VideoFormat.RGB);
修改为
VideoFormat vidformat = new VideoFormat(VideoFormat.YUV);
否则永远也找不到摄像头。

6、把JMF包里的jmf.jar放到Classpath里
7、执行jp.sourceforge.qrcode.example.jmf.jmfexample,搞定

当然,由于源码开放的,只要符合许可,你想怎么改都行,可以把它嵌入到某个应用程序里面,这个程序就具有了扫描QR Code的功能了。

Tags: , , , ,

文章作者: Lee

本文地址: https://www.pomelolee.com/556.html

除非注明,Pomelo Lee文章均为原创,转载请以链接形式标明本文地址

7 Comments to QR Code二维条形码的生成和读取解析和摄像头的读取

苏扬
2010 年 02 月 28 日

看上去有点麻烦 能够说说一下具体用途么?

liyz
2010 年 02 月 28 日

第5章 QR Code二维码应用实例介绍
 5.1 汽车生产指示系统
 5.2 使用二维条码的计量标签系统
 5.3 小型线路板信息的全数管理系统
 5.4 使用QR Code统一账票的零部件采购系统
 5.5 自动化生产线上电子线路板工序管理系统
 5.6 液晶线路板检查系统
 5.9 隐形镜片销售管理系统
 5.10 工具、计量仪器管理系统
 5.11 防止原材料误投入的控制系统
 5.12 常用化学药品成分数据的输入/管理系统
 5.13 市政数据的输入输出系统
 5.14 服装公司进货检验系统
 5.15 QR Code用于饮料物流管理系统
 5.16 人寿保险合同管理系统
 5.17 线路板1D、晶片ID读取系统
 5.18 工作成绩收集系统
 5.19 条码/二维码非接触印字系统
 5.20 发货管理系统
 5.21 印刷地图上同一位置的直接输入、检索系统
 5.22 医药行业的处方签发系统
 5.23 图书馆藏书、录像带管理系统
 5.24 汽车修理厂的修理信息管理系统
 5.25 眼镜销售管理系统
 5.26 QR Code出入库检查系统
第6章 二维条码应用前景分析
 6.1 二维条码在我国推广应用的可行性
 6.2 二维条码市场空间无限
 6.3 二维条码推广应用存在的问题
 6.4 结论
第7章 QR Code二维码应用需求及解决方案
 7.1 QR Code在特殊物品标识上的应用
 7.2 QR Code在资产跟踪过程中的应用
 7.3 QR Code在生产过程控制领域的应用
 7.4 QR Code在物流应用领域
 7.5 QR Code在车辆管理中的应用
 7.6 QR Code在工商管理中的应用
 7.7 QR Code在教育证书中的应用
 7.8 QR Code在身份识别中的应用
 7.9 QR Code在特殊商品防伪上的应用
 7.10 QR Code在文物管理上的应用
用途很广的,有专门的书籍介绍,类似于普通条形码的升级版

G
2011 年 10 月 17 日

用Eclipse可以開嗎??

Pomelo Lee
2011 年 10 月 17 日

可以的执行的

maskiris
2012 年 03 月 09 日

条码内容为何限制了122个字节数以下。
QR码应该能存储更多信息才对啊?

dogdoghao
2012 年 05 月 12 日

有没关于#c的,关于拍照后图片的处理,基本的我已经实现了,只是拍照的时候有一点点得偏差或是模糊都解析不出来,楼主说java有,C#有吗!紧急望尽快回复

Pomelo Lee
2012 年 05 月 13 日

对c#不熟悉,不过我想应该是有的,你可以参考下java的实现方式做下处理,祝你好运~

Leave a comment

Search

文章分类

Links

Meta