/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.pdf417.decoder;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitMatrix;
/**
* <p>
* This class parses the BitMatrix image into codewords.
* </p>
*
* @author SITA Lab (kevin.osullivan@sita.aero)
*/
final class BitMatrixParser {
private static final int MAX_ROW_DIFFERENCE = 6;
private static final int MAX_ROWS = 90;
//private static final int MAX_COLUMNS = 30;
// Maximum Codewords (Data + Error)
private static final int MAX_CW_CAPACITY = 929;
private static final int MODULES_IN_SYMBOL = 17;
private final BitMatrix bitMatrix;
private int rows = 0;
//private int columns = 0;
private int leftColumnECData = 0;
private int rightColumnECData = 0;
private int eraseCount = 0;
private int[] erasures = null;
private int ecLevel = -1;
BitMatrixParser(BitMatrix bitMatrix) {
this.bitMatrix = bitMatrix;
}
/**
* To ensure separability of rows, codewords of consecutive rows belong to
* different subsets of all possible codewords. This routine scans the
* symbols in the barcode. When it finds a number of consecutive rows which
* are the same, it assumes that this is a row of codewords and processes
* them into a codeword array.
*
* @return an array of codewords.
*/
int[] readCodewords() throws FormatException {
int width = bitMatrix.getWidth();
// TODO should be a rectangular matrix
int height = width;
erasures = new int[MAX_CW_CAPACITY];
// Get the number of pixels in a module across the X dimension
//float moduleWidth = bitMatrix.getModuleWidth();
float moduleWidth = 1.0f; // Image has been sampled and reduced
int[] rowCounters = new int[width];
int[] codewords = new int[MAX_CW_CAPACITY];
int next = 0;
int matchingConsecutiveScans = 0;
boolean rowInProgress = false;
int rowNumber = 0;
int rowHeight = 0;
for (int i = 1; i < height; i++) {
if (rowNumber >= MAX_ROWS) {
// Something is wrong, since we have exceeded
// the maximum rows in the specification.
// TODO Maybe return error code
return null;
}
int rowDifference = 0;
// Scan a line of modules and check the
// difference between this and the previous line
for (int j = 0; j < width; j++) {
// Accumulate differences between this line and the
// previous line.
if (bitMatrix.get(j, i) != bitMatrix.get(j, i - 1)) {
rowDifference++;
}
}
if (rowDifference <= moduleWidth * MAX_ROW_DIFFERENCE) {
for (int j = 0; j < width; j++) {
// Accumulate the black pixels on this line
if (bitMatrix.get(j, i)) {
rowCounters[j]++;
}
}
// Increment the number of consecutive rows of pixels
// that are more or less the same
matchingConsecutiveScans++;
// Height of a row is a multiple of the module size in pixels
// Usually at least 3 times the module size
if (matchingConsecutiveScans >= moduleWidth * 2) { // MGMG
// We have some previous matches as well as a match here
// Set processing a unique row.
rowInProgress = true;
}
} else {
if (rowInProgress) {
// Process Row
next = processRow(rowCounters, rowNumber, rowHeight, codewords, next);
if (next == -1) {
// Something is wrong, since we have exceeded
// the maximum columns in the specification.
// TODO Maybe return error code
return null;
}
// Reinitialize the row counters.
for (int j = 0; j < rowCounters.length; j++) {
rowCounters[j] = 0;
}
rowNumber++;
rowHeight = 0;
}
matchingConsecutiveScans = 0;
rowInProgress = false;
}
rowHeight++;
}
// Check for a row that was in progress before we exited above.
if (rowInProgress) {
// Process Row
if (rowNumber >= MAX_ROWS) {
// Something is wrong, since we have exceeded
// the maximum rows in the specification.
// TODO Maybe return error code
return null;
}
next = processRow(rowCounters, rowNumber, rowHeight, codewords, next);
rowNumber++;
rows = rowNumber;
}
erasures = trimArray(erasures, eraseCount);
return trimArray(codewords, next);
}
/**
* Trim the array to the required size.
*
* @param array the array
* @param size the size to trim it to
* @return the new trimmed array
*/
private static int[] trimArray(int[] array, int size) {
if (size > 0) {
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = array[i];
}
return a;
} else {
return null;
}
}
/**
* Convert the symbols in the row to codewords.
* Each PDF417 symbol character consists of four bar elements and four space
* elements, each of which can be one to six modules wide. The four bar and
* four space elements shall measure 17 modules in total.
*
* @param rowCounters an array containing the counts of black pixels for each column
* in the row.
* @param rowNumber the current row number of codewords.
* @param rowHeight the height of this row in pixels.
* @param codewords the codeword array to save codewords into.
* @param next the next available index into the codewords array.
* @return the next available index into the codeword array after processing
* this row.
*/
int processRow(int[] rowCounters, int rowNumber, int rowHeight, int[] codewords, int next)
throws FormatException {
int width = bitMatrix.getWidth();
int columnNumber = 0;
long symbol = 0;
for (int i = 0; i < width; i += MODULES_IN_SYMBOL) {
// This happens in real life and is almost surely a rare misdecode
if (i + MODULES_IN_SYMBOL > rowCounters.length) {
throw FormatException.getFormatInstance();
}
for (int mask = MODULES_IN_SYMBOL - 1; mask >= 0; mask--) {
if (rowCounters[i + (MODULES_IN_SYMBOL - 1 - mask)] >= rowHeight >>> 1) {
symbol |= 1L << mask;
}
}
if (columnNumber > 0) {
int cw = getCodeword(symbol);
// if (debug) System.out.println(" " + Long.toBinaryString(symbol) +
// " cw=" +cw + " ColumnNumber=" +columnNumber + "i=" +i);
if (cw < 0 && i < width - MODULES_IN_SYMBOL) {
// Skip errors on the Right row indicator column
erasures[eraseCount] = next;
next++;
eraseCount++;
} else {
codewords[next++] = cw;
}
} else {
// Left row indicator column
int cw = getCodeword(symbol);
// if (debug) System.out.println(" " + Long.toBinaryString(symbol) +
// " cw=" +cw + " ColumnNumber=" +columnNumber + "i=" +i);
if (ecLevel < 0) {
switch (rowNumber % 3) {
case 0:
break;
case 1:
leftColumnE
android上使用ZXing识别条形码和二维码


在Android平台上进行条形码和二维码的识别与生成,ZXing库是一个不可或缺的工具。ZXing,全称为“Zebra Crossing”,是一个开源项目,提供了多种平台的条码处理能力,包括读取、生成以及解析。在Android应用开发中,ZXing可以方便地集成到项目中,实现快速的扫码功能。 我们要了解ZXing在Android中的核心组件。主要分为两部分:`Core`库和`Android-Intents`库。`Core`库包含了条码处理的核心算法,而`Android-Intents`库则为Android设备提供了专门的接口,使得我们可以直接通过Intent调用系统相机进行扫描。 集成ZXing到Android项目,通常有以下步骤: 1. **添加依赖**:在项目的`build.gradle`文件中,添加ZXing的依赖库。如果是使用Gradle,可以添加如下依赖: ```groovy implementation 'com.google.zxing:core:3.4.1' implementation 'com.journeyapps:zxing-android-embedded:3.6.0' ``` 注意版本号可能会有所不同,确保使用的是最新稳定版。 2. **创建扫描界面**:ZXing提供了一个简单的Intent方式来启动扫描。你只需要创建一个按钮或者触发扫描的事件,然后启动扫描Intent: ```java IntentIntegrator integrator = new IntentIntegrator(this); integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES); integrator.setCameraId(0); // 选择前置或后置摄像头 integrator.setPrompt("扫描二维码"); // 设置扫描提示 integrator.setBeepEnabled(true); // 是否开启扫描成功后的蜂鸣声 integrator.initiateScan(); ``` 3. **处理扫描结果**:你需要重写`onActivityResult`方法来接收扫描结果: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if (result != null) { if (result.getContents() == null) { Toast.makeText(this, "未扫描到数据", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "扫描结果:" + result.getContents(), Toast.LENGTH_SHORT).show(); } } else { super.onActivityResult(requestCode, resultCode, data); } } ``` 4. **自定义扫描视图**:如果需要更高级的定制,例如自定义扫描框样式、动画等,可以使用`ZXingScannerView`类。这个类允许你在界面上直接嵌入扫描视图,提供更多的控制和交互。 5. **生成二维码**:除了扫描,ZXing还支持生成二维码。你可以使用`MultiFormatWriter`和`BitMatrix`来创建一个包含特定数据的二维码,然后转换成位图显示在界面上。 6. **错误处理和权限请求**:别忘了在使用相机功能时,需要检查并请求`CAMERA`权限。同时,处理可能出现的错误,如相机无法访问、扫描失败等情况。 7. **优化性能**:在实际应用中,可能需要对扫描速度、识别率进行优化。这可能涉及到调整扫描参数、设置照明条件等。 通过以上步骤,你可以在Android应用中实现基本的条形码和二维码识别功能。ZXing库的强大之处在于其灵活性和广泛的兼容性,可以根据需求进行不同程度的定制。无论是快速实现基础功能,还是打造专业的扫描应用,ZXing都是一个值得信赖的选择。





















































































































- 1
- 2
- 3
- 4

- #完美解决问题
- #运行顺畅
- #内容详尽
- #全网独家
- #注释完整

- 粉丝: 73
- 资源: 62
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 嵌入式开发中TC397 MCAL最小系统与STM定时器多任务调度的Python编译集成
- 楼宇自控领域冷冻站组态图形的PNG与GIF格式应用及优化
- 欧姆龙CJ系列PLC程序模板:符合日标标准的全功能PLC与触摸屏程序设计
- 三菱F5U系列PLC恒压测试设备开发:ST语言与梯形图结合的应用实例
- 光伏并网逆变器硬件设计与控制算法详解:原理图、PCB、源码及元器件选型
- 20240401资源跨湖
- 电机控制领域的S型速度规划曲线及其Simulink模块实现与优化
- 单相光伏并网Matlab仿真模型:双闭环并网策略与PO扰动法的应用及优化
- 永磁同步电机的非奇异快速终端滑模电流预测控制及其应用
- 基于90C52单片机的28BYJ48步进电机多功能精确控制系统设计
- C# Winform与SunnyUi实现的Modbus-RTU测试程序:提升工控设备调试效率
- MATLAB仿真中光伏板至蓄电池充电的Buck电路设计与优化
- 恒压供水系统:基于PLC与变频器的PID调节及多模式智能控制方案
- 基于SVPWM的三相异步电机直接转矩控制及其Matlab/Simulink仿真模型
- 基于Matlab/Simulink的光伏发电与水力发电仿真:Boost电路与逆变系统关键技术解析
- 100kW光伏并网发电系统MATLAB仿真:基于增量电导+积分调节器的MPPT与VSC控制


