(转)ZXing解析二维码
1 ZXing解析二维码
上一篇文件已经说过如何用ZXing进行生成二维码和带图片的二维码,下面说下如何解析二维码
二维码的解析和生成类似,也可以参考google的一个操作类 BufferedImageLuminanceSource类,该类可在google的测试包中找到,另外j2se中也有该类,你可以将该类直接拷贝到源码中使用,你也可以自己写个。
1.1 BufferedImageLuminanceSource类
package t1; import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import com.google.zxing.LuminanceSource; /**
*
* 二维码的解析需要借助BufferedImageLuminanceSource类,该类是由Google提供的,可以将该类直接拷贝到源码中使用,当然你也可以自己写个
* 解析条形码的基类
*/ public final class BufferedImageLuminanceSource extends LuminanceSource { private static final double MINUS_45_IN_RADIANS = -0.7853981633974483; // Math.toRadians(-45.0) private final BufferedImage image;
private final int left;
private final int top; private static final boolean EXPLICIT_LUMINANCE_CONVERSION;
static {
String property = System.getProperty("explicitLuminanceConversion");
if (property == null) {
property = System.getenv("EXPLICIT_LUMINANCE_CONVERSION");
}
EXPLICIT_LUMINANCE_CONVERSION = Boolean.parseBoolean(property);
} 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); if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) {
this.image = image;
} else {
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.");
} this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY); if (EXPLICIT_LUMINANCE_CONVERSION) { WritableRaster raster = this.image.getRaster();
int[] buffer = new int[width];
for (int y = top; y < top + height; y++) {
image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);
for (int x = 0; x < width; x++) {
int pixel = buffer[x]; // see comments in implicit branch
if ((pixel & 0xFF000000) == 0) {
pixel = 0xFFFFFFFF; // = white
} // .229R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC)
buffer[x] =
(306 * ((pixel >> 16) & 0xFF) +
601 * ((pixel >> 8) & 0xFF) +
117 * (pixel & 0xFF) +
0x200) >> 10;
}
raster.setPixels(left, y, width, 1, buffer);
} } else { // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
// black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
// barcode image. Force any such pixel to be white:
if (image.getAlphaRaster() != null) {
int[] buffer = new int[width];
for (int y = top; y < top + height; y++) {
image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);
boolean rowChanged = false;
for (int x = 0; x < width; x++) {
if ((buffer[x] & 0xFF000000) == 0) {
buffer[x] = 0xFFFFFFFF; // = white
rowChanged = true;
}
}
if (rowChanged) {
image.setRGB(left, y, width, 1, buffer, 0, sourceWidth);
}
}
} // Create a grayscale copy, no need to calculate the luminance manually
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];
}
// The underlying raster of image consists of bytes with the luminance values
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];
// The underlying raster of image consists of area bytes with the luminance values
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);
} /**
* This is always true, since the image is a gray-scale image.
*
* @return true
*/
@Override
public boolean isRotateSupported() {
return true;
} @Override
public LuminanceSource rotateCounterClockwise() {
int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight(); // Rotate 90 degrees counterclockwise.
AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth); // Note width/height are flipped since we are rotating 90 degrees.
BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY); // Draw the original image into rotated, via transformation
Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform, null);
g.dispose(); // Maintain the cropped region, but rotate it too.
int width = getWidth();
return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
} @Override
public LuminanceSource rotateCounterClockwise45() {
int width = getWidth();
int height = getHeight(); int oldCenterX = left + width / 2;
int oldCenterY = top + height / 2; // Rotate 45 degrees counterclockwise.
AffineTransform transform = AffineTransform.getRotateInstance(MINUS_45_IN_RADIANS, oldCenterX, oldCenterY); int sourceDimension = Math.max(image.getWidth(), image.getHeight());
BufferedImage rotatedImage = new BufferedImage(sourceDimension, sourceDimension, BufferedImage.TYPE_BYTE_GRAY); // Draw the original image into rotated, via transformation
Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform, null);
g.dispose(); int halfDimension = Math.max(width, height) / 2;
int newLeft = Math.max(0, oldCenterX - halfDimension);
int newTop = Math.max(0, oldCenterY - halfDimension);
int newRight = Math.min(sourceDimension - 1, oldCenterX + halfDimension);
int newBottom = Math.min(sourceDimension - 1, oldCenterY + halfDimension); return new BufferedImageLuminanceSource(rotatedImage, newLeft, newTop, newRight - newLeft, newBottom - newTop);
} }
1.2 操作类:DecodeTest
package t1; import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable; import javax.imageio.ImageIO; import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer; /**
* 解析二维码
* @author Administrator
*
*/
public class DecodeHelper { public static void main(String[] args) throws Exception {
try {
MultiFormatReader formatReader = new MultiFormatReader();
String filePath = "e:\\new-1.gif"; //new.png
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); Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
hints.put(DecodeHintType.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();
}
}
}
1.3 补充
a.读取二维码图片,并送给 Zxing LuminanceSource 和 Binarizer 两兄弟的处理。
b.处理完的位图和相应的解析参数,交由 MultiFormatReader 处理,并返回解析后的结果。
c.如果对上述 两兄弟的处理 和 MultiFormatReader 的解析有兴趣,可以读读源码。
本博客与二维码相关的文章:
(转)ZXing生成二维码和带logo的二维码,模仿微信生成二维码效果
(转)js jquery.qrcode生成二维码 带logo 支持中文
(转)ZXing解析二维码的更多相关文章
- Android zxing 解析二维码,生成二维码极简demo
zxing 官方的代码很多,看起来很费劲,此demo只抽取了有用的部分,实现了相机预览解码,解析本地二维码,生成二维码三个功能. 简化后的结构如下: 废话少说直接上代码: BaseDecodeHand ...
- ZXing 生成、解析二维码图片的小示例
概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...
- (转)ZXing生成二维码和带logo的二维码,模仿微信生成二维码效果
场景:移动支付需要对二维码的生成与部署有所了解,掌握目前主流的二维码生成技术. 1 ZXing 生成二维码 首先说下,QRCode是日本人开发的,ZXing是google开发,barcode4j也是老 ...
- C#使用zxing,zbar,thoughtworkQRcode解析二维码,附源代码
最近做项目需要解析二维码图片,找了一大圈,发现没有人去整理下开源的几个库案例,花了点时间 做了zxing,zbar和thoughtworkqrcode解析二维码案例,希望大家有帮助. zxing是谷歌 ...
- 使用zxing生成解析二维码
1. 前言 随着移动互联网的发展,我们经常在火车票.汽车票.快餐店.电影院.团购网站以及移动支付等各个场景下见到二维码的应用,可见二维码以经渗透到人们生活的各个方面.条码.二维码以及RFID被人们应用 ...
- java zxing实现二维码生成和解析zxing实现二维码生成和解析
原文:https://www.cnblogs.com/zhangzhen894095789/p/6623041.html zxing实现二维码生成和解析 二维码 zxing 二维码的生成与解析 ...
- Java使用Zxing生成、解析二维码工具类
Zxing是Google提供的关于条码(一维码.二维码)的解析工具,提供了二维码的生成与解析的方法. 1.二维码的生成 (1).将Zxing-core.jar 包加入到classpath下. (2). ...
- Java使用ZXing生成/解析二维码图片
ZXing是一种开源的多格式1D/2D条形码图像处理库,在Java中的实现.重点是在手机上使用内置摄像头来扫描和解码设备上的条码,而不与服务器通信.然而,该项目也可以用于对桌面和服务器上的条形码进行编 ...
- 使用Google提供的ZXing Core,Java生成、解析二维码
1.maven项目中,pom.xml中引入ZXing Core工具包: <!-- https://mvnrepository.com/artifact/com.google.zxing/core ...
随机推荐
- 用 BeautifulSoup爬取58商品信息
最近对Python爬虫比较迷恋,看了些爬虫相关的教程 于是乎跟着一起爬取了58上面的一些商品信息,并存入到xlsx文件中,并通过xlsxwirter的方法给表格设置了一些格式.好了,直接贴代码吧~ # ...
- Hadoop 2.7 伪分布式环境搭建
1.安装环境 ①.一台Linux CentOS6.7 系统 hostname ipaddress subnet mask ...
- 在Linux与Windows上获取当前堆栈信息
在编写稳定可靠的软件服务时经常用到输出堆栈信息,以便用户/开发者获取准确的运行信息.常用在日志输出,错误报告,异常检测. 在Linux有比较简便的函数获取堆栈信息: #include <stdi ...
- select change事件给其它元素赋值,本select的value或tex
select change事件给其它元素赋值,本select的value或textonchange='$("#areaname").val($("option:selec ...
- 常用PHP函数的封装
PHP获取文件扩展名(后缀) function getExtension($filename){ $myext = substr($filename, strrpos($filename, '.')) ...
- iis部署wcf服务过程
一.在iis网站中添加wcf服务,一直添加到web.config目录即可 二.点击基本设置-->连接为-->特定用户.填写登入电脑的用户名和密码. 三.点击身份验证 四.控制面板,设置防火 ...
- 日常API之百度翻译
百度翻译是什么,可以吃吗?相信很多人都熟悉,它是我们生活中必不可少的一只东东. 但是,百度翻译开发平台只有每月只能翻译200万个字符,多出的要按照49.00/百万字符来算.对于我酱紫的乞丐程序员来说, ...
- Tomcat常用配置修改
Tomcat常用配置修改 说明 运行需要设置环境变量 JAVA_HOME 即JDK安装目录 tomcat 默认登录地址 http://localhost:8080 配置tomcat 1.端口设置 打开 ...
- 不错的 HttpHelper类 c#
/// <summary>/// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理/// 重要提示: ...
- struts2框架下的一个简单的ajax例子
举个例子 jsp页面: <%@ page language="java" import="java.util.*" pageEncoding=" ...