二维码之zxing二维码解析图片资源
2015-01-14 17:48
302 查看
zxing针对不同开发平台,都给出了解析二维码的例子,我这里只聊聊关于android系统的解析。
对于android手机来说,二维码图像获取方式有拍照扫描,以及读取本地图片资源。无论是哪种方式,解析过程的核心内容基本是一样的。关于手机拍照扫描这块,由于要涉及到很多问题要讲,所以我打算把这块放在下篇文章再细致讲解,这次只讲如何对图片进行解析。
首先,和生成二维码一样,我们要告诉系统解析二维码的设置参数。这里我选择了支持主流的三类方式,其中一种为一维码(条形码)。设置解析的字符位UTF8。如果不设置字符解析方式,它会自己去识别内容,然后自己判断该用哪种方式。
看一下设置参数的代码:
[java]
view plaincopyprint?
MultiFormatReader multiFormatReader = new MultiFormatReader();
// 解码的参数
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(
2);
// 可以解析的编码类型
Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>();
if (decodeFormats == null || decodeFormats.isEmpty()) {
decodeFormats = new Vector<BarcodeFormat>();
// 这里设置可扫描的类型,我这里选择了都支持
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
}
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
// 设置继续的字符编码格式为UTF8
// hints.put(DecodeHintType.CHARACTER_SET, "UTF8");
// 设置解析配置参数
multiFormatReader.setHints(hints);
补一句:zxing源码中对UTF8的定义字符串内容不是UTF-8,而是UTF8。
private static final String UTF8 = "UTF8";
再来就是解析部分:
[java]
view plaincopyprint?
// 开始对图像资源解码
Result rawResult = null;
try {
rawResult = multiFormatReader
.decodeWithState(new BinaryBitmap(new HybridBinarizer(
new BitmapLuminanceSource(BitmapFactory
.decodeResource(getResources(),
R.drawable.weibo)))));
} catch (NotFoundException e) {
e.printStackTrace();
}
按照zxing的解码规则,需要传入一个LuminanceSource类的对象,最后就会得到解析结果result对象,也就是解码后的信息类。这里唯一需要自己实现的就是BitmapLuminanceSource类。
BitmapLuminanceSource继承自LuminanceSource这个抽象类,需要实现它的构造方法,并重载getMatrix()和getRow(int y, byte[] row)方法。其构造方法中需要传入宽高,这两个值指的就是图片的宽和高。getMatrix()方法会返回一个byte数组,这个数组就是图片的像素数组。getRow(int y, byte[] row)如字面的意义,就是得到图片像素数组的一行。其中的y就是需要的哪一个行的像素数组。
先看构造方法:
[java]
view plaincopyprint?
protected BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
// 首先,要取得该图片的像素数组内容
int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
// 将int数组转换为byte数组
for (int i = 0; i < data.length; i++) {
this.bitmapPixels[i] = (byte) data[i];
}
}
注意:这里的byte数组是指图片的像素数组,而不是所谓Bitmap转换成byte数组,有人出现解析的错误,大多是对这个参数用途没理解造成的。
Bitmap对象的getPixels方法可以取得的像素数组,但它得到是int型数组。根据其api文档解释,取得的是color,也就是像素颜色值。每个像素值包含透明度,红色,绿色,蓝色。所以白色就是0xffffffff,黑色就是0xff000000。直接由int型转成byte型,实现上相当于我们这里只取其蓝色值部分。
再来就是getRow方法:
[java]
view plaincopyprint?
@Override
public byte[] getRow(int y, byte[] row) {
// 这里要得到指定行的像素数据
System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
return row;
}
补充:getPixels得到的像素数组是一维的,也就是按照图片宽度逐行取像素颜色值录入。如果想得到单行的像素数组内容,通过y*width就可以找该行的第一个像素值,拷贝后面width个就可以得到该行的像素内容。
最后一个就是getMatrix()方法,它用来返回我们的图像转换成的像素数组。
[java]
view plaincopyprint?
@Override
public byte[] getMatrix() {
// 返回我们生成好的像素数据
return bitmapPixels;
}
以下是完整的BitmapLuminanceSource类:
[java]
view plaincopyprint?
public class BitmapLuminanceSource extends LuminanceSource {
private byte bitmapPixels[];
protected BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
// 首先,要取得该图片的像素数组内容
int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
// 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容
for (int i = 0; i < data.length; i++) {
this.bitmapPixels[i] = (byte) data[i];
}
}
@Override
public byte[] getMatrix() {
// 返回我们生成好的像素数据
return bitmapPixels;
}
@Override
public byte[] getRow(int y, byte[] row) {
// 这里要得到指定行的像素数据
System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
return row;
}
}
好了,最后就得到了我们想要的Result对象。
这个对象中包含了很多内容,包括内容,编码方式,解析时间等。
我们想要的内容就放在rawResult.getText()中,你还可以得到它的编码方式rawResult.getBarcodeFormat()。
zxing针对不同开发平台,都给出了解析二维码的例子,我这里只聊聊关于android系统的解析。
对于android手机来说,二维码图像获取方式有拍照扫描,以及读取本地图片资源。无论是哪种方式,解析过程的核心内容基本是一样的。关于手机拍照扫描这块,由于要涉及到很多问题要讲,所以我打算把这块放在下篇文章再细致讲解,这次只讲如何对图片进行解析。
首先,和生成二维码一样,我们要告诉系统解析二维码的设置参数。这里我选择了支持主流的三类方式,其中一种为一维码(条形码)。设置解析的字符位UTF8。如果不设置字符解析方式,它会自己去识别内容,然后自己判断该用哪种方式。
看一下设置参数的代码:
[java]
view plaincopyprint?
MultiFormatReader multiFormatReader = new MultiFormatReader();
// 解码的参数
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(
2);
// 可以解析的编码类型
Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>();
if (decodeFormats == null || decodeFormats.isEmpty()) {
decodeFormats = new Vector<BarcodeFormat>();
// 这里设置可扫描的类型,我这里选择了都支持
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
}
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
// 设置继续的字符编码格式为UTF8
// hints.put(DecodeHintType.CHARACTER_SET, "UTF8");
// 设置解析配置参数
multiFormatReader.setHints(hints);
MultiFormatReader multiFormatReader = new MultiFormatReader(); // 解码的参数 Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>( 2); // 可以解析的编码类型 Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>(); if (decodeFormats == null || decodeFormats.isEmpty()) { decodeFormats = new Vector<BarcodeFormat>(); // 这里设置可扫描的类型,我这里选择了都支持 decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); } hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); // 设置继续的字符编码格式为UTF8 // hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置解析配置参数 multiFormatReader.setHints(hints);
补一句:zxing源码中对UTF8的定义字符串内容不是UTF-8,而是UTF8。
private static final String UTF8 = "UTF8";
再来就是解析部分:
[java]
view plaincopyprint?
// 开始对图像资源解码
Result rawResult = null;
try {
rawResult = multiFormatReader
.decodeWithState(new BinaryBitmap(new HybridBinarizer(
new BitmapLuminanceSource(BitmapFactory
.decodeResource(getResources(),
R.drawable.weibo)))));
} catch (NotFoundException e) {
e.printStackTrace();
}
// 开始对图像资源解码 Result rawResult = null; try { rawResult = multiFormatReader .decodeWithState(new BinaryBitmap(new HybridBinarizer( new BitmapLuminanceSource(BitmapFactory .decodeResource(getResources(), R.drawable.weibo))))); } catch (NotFoundException e) { e.printStackTrace(); }
按照zxing的解码规则,需要传入一个LuminanceSource类的对象,最后就会得到解析结果result对象,也就是解码后的信息类。这里唯一需要自己实现的就是BitmapLuminanceSource类。
BitmapLuminanceSource继承自LuminanceSource这个抽象类,需要实现它的构造方法,并重载getMatrix()和getRow(int y, byte[] row)方法。其构造方法中需要传入宽高,这两个值指的就是图片的宽和高。getMatrix()方法会返回一个byte数组,这个数组就是图片的像素数组。getRow(int y, byte[] row)如字面的意义,就是得到图片像素数组的一行。其中的y就是需要的哪一个行的像素数组。
先看构造方法:
[java]
view plaincopyprint?
protected BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
// 首先,要取得该图片的像素数组内容
int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
// 将int数组转换为byte数组
for (int i = 0; i < data.length; i++) {
this.bitmapPixels[i] = (byte) data[i];
}
}
protected BitmapLuminanceSource(Bitmap bitmap) { super(bitmap.getWidth(), bitmap.getHeight()); // 首先,要取得该图片的像素数组内容 int[] data = new int[bitmap.getWidth() * bitmap.getHeight()]; this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()]; bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight()); // 将int数组转换为byte数组 for (int i = 0; i < data.length; i++) { this.bitmapPixels[i] = (byte) data[i]; } }
注意:这里的byte数组是指图片的像素数组,而不是所谓Bitmap转换成byte数组,有人出现解析的错误,大多是对这个参数用途没理解造成的。
Bitmap对象的getPixels方法可以取得的像素数组,但它得到是int型数组。根据其api文档解释,取得的是color,也就是像素颜色值。每个像素值包含透明度,红色,绿色,蓝色。所以白色就是0xffffffff,黑色就是0xff000000。直接由int型转成byte型,实现上相当于我们这里只取其蓝色值部分。
再来就是getRow方法:
[java]
view plaincopyprint?
@Override
public byte[] getRow(int y, byte[] row) {
// 这里要得到指定行的像素数据
System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
return row;
}
@Override public byte[] getRow(int y, byte[] row) { // 这里要得到指定行的像素数据 System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth()); return row; }
补充:getPixels得到的像素数组是一维的,也就是按照图片宽度逐行取像素颜色值录入。如果想得到单行的像素数组内容,通过y*width就可以找该行的第一个像素值,拷贝后面width个就可以得到该行的像素内容。
最后一个就是getMatrix()方法,它用来返回我们的图像转换成的像素数组。
[java]
view plaincopyprint?
@Override
public byte[] getMatrix() {
// 返回我们生成好的像素数据
return bitmapPixels;
}
@Override public byte[] getMatrix() { // 返回我们生成好的像素数据 return bitmapPixels; }
以下是完整的BitmapLuminanceSource类:
[java]
view plaincopyprint?
public class BitmapLuminanceSource extends LuminanceSource {
private byte bitmapPixels[];
protected BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
// 首先,要取得该图片的像素数组内容
int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
// 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容
for (int i = 0; i < data.length; i++) {
this.bitmapPixels[i] = (byte) data[i];
}
}
@Override
public byte[] getMatrix() {
// 返回我们生成好的像素数据
return bitmapPixels;
}
@Override
public byte[] getRow(int y, byte[] row) {
// 这里要得到指定行的像素数据
System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
return row;
}
}
public class BitmapLuminanceSource extends LuminanceSource { private byte bitmapPixels[]; protected BitmapLuminanceSource(Bitmap bitmap) { super(bitmap.getWidth(), bitmap.getHeight()); // 首先,要取得该图片的像素数组内容 int[] data = new int[bitmap.getWidth() * bitmap.getHeight()]; this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()]; bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight()); // 将int数组转换为byte数组,也就是取像素值中蓝色值部分作为辨析内容 for (int i = 0; i < data.length; i++) { this.bitmapPixels[i] = (byte) data[i]; } } @Override public byte[] getMatrix() { // 返回我们生成好的像素数据 return bitmapPixels; } @Override public byte[] getRow(int y, byte[] row) { // 这里要得到指定行的像素数据 System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth()); return row; } }
好了,最后就得到了我们想要的Result对象。
这个对象中包含了很多内容,包括内容,编码方式,解析时间等。
我们想要的内容就放在rawResult.getText()中,你还可以得到它的编码方式rawResult.getBarcodeFormat()。
相关文章推荐
- 二维码之zxing二维码解析图片资源
- ZXing之二维码解析图片资源
- 解决Zxing解析本地图片二维码,识别率低,识别不出来的问题!
- ZXing 生成、解析二维码图片的小示例
- Zxing图片识别 从相册选二维码图片解析总结
- JAVA 压缩图片-解析一维码二维码-ZXING
- Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- Android平台利用Zxing生成二维码与解析图片中的二维码
- 使用zxing解析二维码图片
- Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- Java使用谷歌的zxing生成二维码Qrcode并解析提取二维码图片内容
- [置顶] Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等
- java中ZXing 生成、解析二维码图片的小示例
- Zxing图片识别 从相册选取二维码图片进行解析总结
- 使用zxing生成二维码图片,并解析
- Zxing图片识别 从相册选二维码图片解析总结
- .net如何解析二维码图片
- 使用zxing 生成和解析二维码
- java zxing 生成带图片的二维码
- 二维码图片生成和解析工具类