目标解码模拟激光条码扫描器的行为。然而,阅读器不是看整个视野,而是试图解码仅位于激光瞄准点下方的条形码。这可以防止操作员意外读取其他附近的条形码。
支持设备:
配置dmcc:
启用或禁用目标解码(或检索它的状态)。
默认值:OFF
例子
readerDevice.getDataManSystem()。sendCommand(“设置解码器。TARGET-DECODING”);
readerDevice.getDataManSystem()。sendCommand(“设置解码器。TARGET-DECODING”);
self.readerDevice.dataManSystem()。sendCommand(“设置解码器。TARGET-DECODING”)
[self.readerDevice。dataManSystem sendCommand:@"SET DECODER. "TARGET-DECODING”);
设置(或获取)居中窗口的大小。数字以图像的百分比表示。
如果条形码与居中窗口重叠,则该条形码将被解码。因此,居中窗口不一定需要包含整个条形码。
缺省值:50 50 10 10
例子
readerDevice.getDataManSystem()。sendCommand(“设置解码器。居中窗50 50 5 5”);
self.readerDevice.dataManSystem()。sendCommand(“设置解码器。居中窗50 50 5 5")
[self.readerDevice。dataManSystem sendCommand:@"SET DECODER. "居中窗50 50 5 5"];
如果将居中窗口添加到SVG结果中,则设置(或获取)。
缺省值:ON
例子
readerDevice.getDataManSystem()。sendCommand(“设置解码器。DISPLAY-TARGET”);
self.readerDevice.dataManSystem()。sendCommand(“设置解码器。DISPLAY-TARGET”)
[self.readerDevice。dataManSystem sendCommand:@"SET DECODER. "DISPLAY-TARGET”);
备注
下面是在摄像头AP中启用目标解码时摄像头扫描预览的例子(黄色的小矩形是目标解码窗口)I:
目标解码窗口(矩形)的颜色和线条的重量可以改变:
MWOverlay。targetRectLineColor = Color.RED;MWOverlay。targetRectLineWidth = 2;
MWOverlay.setTargetRectLineUIColor (UIColor.red) MWOverlay.setTargetRectLineWidth (2)
[MWOverlay setTargetRectLineUIColor:[UIColor redColor]];[MWOverlay setTargetRectLineWidth: 2];
如果你想一次扫描更多的条形码,在一个扫描会话,你可以使用多码阅读。
支持设备:
配置dmcc:
设置解码器为成功读取结果应找到的编码数。
缺省值:1
例子
readerDevice.getDataManSystem()。sendCommand(“多码。NUM-CODES 3”);
self.readerDevice.dataManSystem()。sendCommand(“多码。NUM-CODES 3”)
[self.readerDevice。dataManSystem sendCommand:@"SET MULTICODE. "NUM-CODES 3”);
定义读者如何解释要查找的代码数量。
默认值:OFF
例子
readerDevice.getDataManSystem()。sendCommand(“多码。部分结果”);
self.readerDevice.dataManSystem()。sendCommand(“多码。部分结果”)
[self.readerDevice。dataManSystem sendCommand:@"SET MULTICODE. "部分结果”);
如果该代码是在最后N次读取中读取的,则不要读取。
默认值:0(不限制)
例子
readerDevice.getDataManSystem()。sendCommand(“设置解码器。REREAD-NOT-LAST-N 1 ");
self.readerDevice.dataManSystem()。sendCommand(“设置解码器。REREAD-NOT-LAST-N 1”)
[self.readerDevice。dataManSystem sendCommand:@"SET DECODER. "REREAD-NOT-LAST-N 1 ");
定义每个符号组的期望最大代码数:
任何单个符号的期望值都不能超过参数MULTICODE。NUM-CODES,要查找的代码总数。第一个参数是符号组,第二个参数是最大码数。
缺省值:所有组为1
例子
readerDevice.getDataManSystem()。sendCommand(“多码。Max-num-codes 1 3");
self.readerDevice.dataManSystem()。sendCommand(“多码。Max-num-codes 1 3")
[self.readerDevice。dataManSystem sendCommand:@"SET MULTICODE. "Max-num-codes 1 3"];
备注
如果启用了多码读取,则在onReadResultReceived回调函数中通过使用获取所有结果的列表getSubResults ()ReadResults对象的方法。如果禁用多码读取,此方法返回null。
解析器帮助我们将解码结果提取为结构化格式(JSON, Key-Value)用于搜索、排序和验证。有六种类型的解析器:
此外,在cmbSDK中还有使用AUTO解析器类型的选项,它会试图找到哪一个最适合。
支持设备:
使用setParser ()方法来设置您想使用的解析器类型,或者getParser ()获取所选类型。在有效连接到阅读器设备后设置解析器类型。默认为无。
例子
readerDevice.setParser (ResultParser.AAMVA);
self.readerDevice.parser = CMBResultParserAAMVA
self.readerDevice.parser = CMBResultParserAAMVA;
启用所需解析器类型后,您可以在ReadResult的onReadResultReceived回调函数中从接收到的结果中获得结构化格式:
//返回结果中解析后的json格式的文本。//返回结果的解析文本results.getResultAt(0).getParsedText();
let results:[CMBReadResult] = readResults?readResults一样吗?(CMBReadResult) ? ?[] //从结果中返回解析后的json格式的文本let parsedJSON = results.first?parsedJSON //返回结果的解析文本let parsedText = results.first
NSArray* results = readResults.readResults;//从结果返回解析后的json格式的文本NSString* parsedJSON = [[results firstObject] parsedJSON];NSString* parsedText = [[results firstObject] parsedText];
您可以使用此功能指定将用于定位和解码符号的图像的确切区域。如果两个条形码彼此靠近,并且您需要确保只读取目标区域的代码,那么这将很有帮助。减少感兴趣的区域并不一定会减少解码时间或增加图像传输速率。
支持设备:
配置dmcc:
(获取|设置)译码器。roi百分比[x w y h]
检查0-100的范围,宽度和高度的最小值为5,以及参数之间隐含的约束,例如给定轴的总和不超过100。
例子
readerDevice.getDataManSystem()。sendCommand(“设置解码器。Roi-percent 10 80 10 80”);
self.readerDevice.dataManSystem()。sendCommand(“设置解码器。Roi-percent 10 80 10 80”)
[self.readerDevice。dataManSystem sendCommand:@"SET DECODER. "Roi-percent 10 80 10 80"];
SDK可以解码图像文件中的条形码(仅限摄像头API)。支持的图片格式包括BMP、PNG和JPG。图像不能大于5000 x 5000像素。
支持设备:
要扫描图像,应用程序必须首先将图像读入内存,然后使用的形象。负载DMCC命令来解码。对象readerDevice必须在发送的形象。负载命令。下面是一个使用sendCommand方法初始化的形象。负载函数。
例子
readerDevice.getDataManSystem () .sendCommand (String.format”的形象。负载%d", imageData.length), imageData, 500, false, (dataManSystem, response) -> { if (response.getError() != null) { // IMAGE.LOAD DMCC finished with error, handle the error here } });
self.readerDevice.dataManSystem () ? .sendCommand(”的形象。负载\(imageData.count)", with: imageData, timeout: 100, expectBinaryResponse: false, callback: { (response) in if response?.status != DMCC_STATUS_NO_ERROR { // IMAGE.LOAD DMCC finished with error, handle the error here } })
注:imageData为图像的数据。
[self.readerDevice。dataManSystem sendCommand:[NSString stringWithFormat:@"IMAGE. txt]负载%lu", [imageData length]] withData:imageData timeout:100 expectBinaryResponse:NO callback:^(CDMResponse *response) { if (response.status != DMCC_STATUS_NO_ERROR) { // IMAGE.LOAD DMCC finished with error, handle the error here } }];
注:imageData是图像的NSData。
就像实时扫描一样,当的形象。负载命令完成后,结果将在您的读取结果数组中接收ReaderDevice的委托使用以下方法:
void onReadResultReceived(ReaderDevice reader, ReadResults result)
func didReceiveReadResult(fromReader reader: CMBReaderDevice, results readResults: CMBReadResults!)
- (void)didReceiveReadResultFromReader:(CMBReaderDevice *)reader results:(CMBReadResults *)readResults;
下面是一个从设备的照片库中选择和扫描图像的示例
private void pickImageFromGallery(){意图pickPhoto =新的意图(意图。ACTION_PICK android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult (pickPhoto PICK_IMAGE);} @覆盖受保护无效onActivityResult(int requestCode, int resultCode, Intent data) {if(requestCode == PICK_IMAGE && resultCode == RESULT_OK && data != null && data. getdata () != null && readerDevice != null && readerDevice. getconnectionstate () == ConnectionState.Connected) {try (InputStream imageStream = getContentResolver().openInputStream(data. getdata ());ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {int nRead;字节[]字节=新字节[1024];while ((nRead = imageStream。读取(bytes, 0, bytes.length)) != -1){缓冲区。write(bytes, 0, nRead);} buffer.flush ();final byte[] byteArray = buffer.toByteArray(); readerDevice.getDataManSystem().sendCommand(String.format("IMAGE.LOAD %d", byteArray.length), byteArray, 500, false, (dataManSystem, response) -> { if (response.getError() != null) { Toast.makeText(MainActivity.this, "ERROR [" + response.getError().toString() + "]: " + response.getError().getLocalizedMessage(), Toast.LENGTH_LONG).show(); } }); } catch (IOException e) { e.printStackTrace(); } } super.onActivityResult(requestCode, resultCode, data); }
func showImagePicker() {let imagePickerController = UIImagePickerController() imagePickerController。allowsEditing = false imagePickerController.delegate = self imagePickerController。sourceType = . photolibrary self。// MARK: UIImagePickerControllerDelegate methods func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController, animated: true, completion: nil]} // MARK: UIImagePickerControllerDelegate methods func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo)InfoKey: Any]){选择器。release (animated: true, completion: nil) let imagePath = info[UIImagePickerController.InfoKey. info]imageURL] !NSURL守卫让imageData = try?数据。init(contentsOf: imagePath.absoluteURL!) else {return} self.readerDevice.dataManSystem()?负载\(imageData.count)", with: imageData, timeout: 100, expectBinaryResponse: false, callback: { (response) in if response?.status != DMCC_STATUS_NO_ERROR { // IMAGE.LOAD DMCC finished with error, handle the error here } }) }
- (void)showImagePicker {UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];imagePickerController。allowsEditing = NO;imagePickerController.delegate = self;[imagePickerController setSourceType: UIImagePickerControllerSourceTypePhotoLibrary];[self presentViewController:imagePickerController animated:YES completion:nil];} #pragma mark - UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{[self disdisviewcontrolleranimated:YES completion:nil];NSURL *imagePath = [info valueForKey:UIImagePickerControllerImageURL];NSData *imageData = [NSData dataWithContentsOfURL:imagePath];if (imageData) {[self.readerDevice.]dataManSystem sendCommand:[NSString stringWithFormat:@"IMAGE. txt]负载 %lu", [imageData length]] withData:imageData timeout:100 expectBinaryResponse:NO callback:^(CDMResponse *response) { if (response.status != DMCC_STATUS_NO_ERROR) { // IMAGE.LOAD DMCC finished with error, handle the error here } }]; } }
由于在一些一维条形码中缺乏错误纠正,甚至校验和值,许多条形码易于误读和短读(其中只有一部分条形码被解码)。打印质量差、光线不一致、图像模糊、偏斜和其他变量都可能造成这种情况。
SDK减轻误读和短读的方法之一是使用一种称为位置验证的功能。启用后,SDK将更加努力地验证一维条形码的边缘和完整位置;从而极大地减少读取错误。请注意,位置验证可能会降低扫描性能,特别是当启用了多个符号或在具有较慢cpu的值线设备上使用时。
位置验证可用于以下条形码类型(粗体部分默认启用此功能):代码11,代码25,Codabar代码93,代码39,代码128Telepen,MSI普莱西UPC / EAN。
在处理读取错误时,可以考虑将位置验证与SDK的其他功能结合使用,例如设置最小读取长度和调整解码器的努力级别(请参阅DMCC命令decoder . effort)。
支持设备:
配置API:
例子
BarcodeScanner.MWBsetParam (BarcodeScanner。MWB_CODE_MASK_39 BarcodeScanner。MWB_PAR_ID_VERIFY_LOCATION BarcodeScanner.MWB_PAR_VALUE_VERIFY_LOCATION_ON);
MWB_setParam(MWB_CODE_MASK_39, UInt32(MWB_PAR_ID_VERIFY_LOCATION), UInt32(MWB_PAR_VALUE_VERIFY_LOCATION_ON))
MWB_setParam(MWB_CODE_MASK_39, MWB_PAR_ID_VERIFY_LOCATION, mwb_par_value_verify_location);
默认情况下,当您使用摄像头API创建阅读器设备时,使用全屏预览。如果你想使用部分屏幕预览,你需要创建ViewGroup容器在你的布局的android或视图容器,然后将容器作为参数发送到阅读器设备构造函数中,否则如果该参数未设置或如果零设置后,将使用全屏预览。
当使用部分屏幕预览时,来自相机的帧被填充在预览容器中,如果预览容器的纵横比与相机纵横比不同,我们将执行裁剪以避免扭曲。
支持设备:
例子
首先在布局/故事板中创建容器。
<?XML版本="1.0"编码="utf-8"?> < android.support.constraint。ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#333333" tools:context="cognex.com.cmbcamerademo.ScannerActivity"> ....
稍后,当您创建阅读器设备时,将该容器作为阅读器设备构造函数中的参数发送
readerDevice =读写设备。getPhoneCameraDevice(this, param_cameraMode, PreviewOption。default, (ViewGroup) findViewById(R.id.rlPreviewContainer));
将新添加的UIView连接到ViewController中的outlet
@IBOutlet弱var previewContainer: UIView!
然后在构造函数中使用previewContainer作为参数创建readerDevice
let readerDevice = CMBReaderDevice。readerOfDeviceCamera(:自我。cameraMode previewOptions: CDMPreviewOption。init(rawValue: 0), previewView:self.previewContainer)
将新添加的UIView连接到ViewController中的outlet
IBOutlet UIView *previewContainer;
然后在构造函数中使用previewContainer作为参数创建readerDevice
CMBReaderDevice *readerDevice = [CMBReaderDevice readerOfDeviceCameraWithCameraMode:cameraMode previewOptions:kCDMPreviewOptionDefaults previewView:self.previewContainer];
这是它的样子