private void openCamera(){// 获取 CameraKit 对象cameraKit = CameraKit.getInstance(this);
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
| private void openCamera(){ cameraKit = CameraKit.getInstance(this); if (cameraKit == null) { return; } try { String[] cameraIds = cameraKit.getCameraIds(); if (cameraIds.length <= 0) { System.out.println("cameraIds size is 0"); } CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl(); if(cameraStateCallback ==null) { System.out.println("cameraStateCallback is null"); } EventHandler eventHandler = new EventHandler(EventRunner.create("CameraCb")); if(eventHandler ==null) { System.out.println("eventHandler is null"); } cameraKit.createCamera(cameraIds[0], cameraStateCallback, eventHandler); } catch (IllegalStateException e) { System.out.println("getCameraIds fail"); }
|
2、绑定相机的Surface
Surface用于实现相机的预览、拍照、录像等功能。此处为相机添加:previewSurface和 dataSurface。前者用来展示相机拍摄到的界面;后者用来读取并处理相机拍摄到的数据信息。
1 2 3 4 5 6 7 8
| private final class CameraStateCallbackImpl extends CameraStateCallback { @Override public void onCreated(Camera camera) { mcamera = camera; CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder(); if (cameraConfigBuilder == null) { System.out.println("onCreated cameraConfigBuilder is null");
|
}
1 2 3 4 5 6 7 8 9 10 11
| // 配置预览的 Surface cameraConfigBuilder.addSurface(previewSurface) // 配置处理数据的Surface dataSurface = imageReceiver.getRecevingSurface() cameraConfigBuilder.addSurface(dataSurface) try { // 相机设备配置 camera.configure(cameraConfigBuilder.build()) } catch (IllegalArgumentException e) { System.out.println("Argument Exception") System.out.println("State Exception")
|
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 3、开启循环帧捕获 用户一般在画面生成后,才执行拍照或者其他操作。开启循环帧捕获后,dataSurface可以获得来自相机的数据。
public void onConfigured(Camera camera) { FrameConfig.Builder frameConfigBuilder = mcamera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW); frameConfigBuilder.addSurface(previewSurface); frameConfigBuilder.addSurface(dataSurface); try { int triggerId = mcamera.triggerLoopingCapture(frameConfigBuilder.build()); }
|
4、扫描相机数据
dataSurface中的数据为相机原始数据,其格式为YUV420,需要将其封装为Image类的数据才能执行传入ImageScanner类进行正式扫描。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Image barcode = new Image(mImage.getImageSize().width,mImage.getImageSize().height, "Y800"); barcode.setData(YUV_DATA);
int result = scanner.scanImage(barcode);
5、显示预览数据的扫描结果 由于对准器中的条形码可能不止一个,ImageScanner类的扫描结果可能也有多个,因此最后返回的扫描结果是SymbolSet类型,此数据类型是可以盛纳多个Symbol数据的容器,每个Symbol数据代表一个条形码的扫描结果。
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) { handler.postTask(new Runnable() { public void run() { scanText.setText("扫描结果:" + sym.getData()); scanText.invalidate(); } });
|
Library解析
Library部分主要是对dataSurface的数据进行扫描,此处主要涉及两个功能:(1)相机原始数据封装为Image数据;(2)对Image数据进行扫描。由于这部分主要由C语言实现,所以此处只解析大概原理,展示主要接口,不再进行底层代码的展示。
(1)相机原始数据封装为Image数据
1 2
| Image支持多种数据格式,包括常见的YUV以及RGB数据。此处需要的Image数据是“Y800”类型或者“GRAY”类型,即条形码的扫描数据仅需要图像的灰度数据。 `public native void setData(byte[] data);` (2)对Image数据进行扫描 使用scanImage()方法对传入的Image数据进行扫描。该过程首先对传入的图像进行配置校验,然后以一个像素点为增量逐行扫描,扫描路径为Z字型,并且完成对扫描数据的滤波,求取边缘梯度,梯度阈值自适应,确定边缘等操作,最后将扫描据转化成明暗宽度流。 通过明暗宽度流的变化格律可以知道当前正在被扫描的条形码的种类,然后依据固定的解码方法进行解码,便可得到条形码信息。 `public native int scanImage(Image image);` 项目贡献人
|
陈丛笑 郑森文 朱伟 陈美汝 张馨心
想了解更多内容,请访问51CTO和华为合作共建的鸿蒙社区:https://harmonyos.51cto.com/
本文标题: 鸿蒙开源第三方组件——Zbar_ohos条形码阅读器
发布时间: 2019年05月14日 00:00
最后更新: 2026年09月16日 05:40
原始链接: https://haoxiang.eu.org/387f985e/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!