Directory:

1. Component effect display

2. Sample analysis

3. Library parsing

4, “Hongmeng Open source third-party documents” series of articles collection

5, Hongmeng free public courses

preface

Bar code Reader control ZBar based on Android platform (github.com/ZBar/ZBar)

The code has been open sourced to (gitee.com/isrc\_ohos/…

Welcome to download and use and put forward valuable advice!

background

Zbar-ohos is A bar Code reader based on Hongmon system, supporting EAN-13 / UPC-A, UPC-E, EAN-8, Code 128, CODE39, Codabar and QR Code recognition, has been widely used in scan Code registration, scan Code viewing, scan Code login and other fields.

Component Effect display

1. Add permissions

After opening the software, the prompt for adding camera permissions as shown in Figure 1 will be displayed. Click the “Always Allow” button and restart the software (refresh the UI interface) to scan the barcode.

Figure 1 Scanning two-dimensional code interface

2. Scanning effect

The scan interface consists of two parts: the aligner and the status bar. The aligner displays the picture taken by the camera, and the bar code needs to be in this range before it can be scanned. The status bar displays the current scan status or scan result.

(1) One-dimensional bar code scanning

One-dimensional barcodes generally express information in the horizontal direction and no information in the vertical direction. The height is usually fixed for easy reading by the aligner.

A rendering of the ZBar component scanning a one-dimensional bar code is shown in Figure 2. When the camera scans the bar code, the display content in the status bar below changes from “scanning” to the scanning result of the bar code. When the next bar code is scanned, the scanning result of the status bar is updated in real time.

Figure 2 Barcode scanning results

(2) two-dimensional barcode scanning

Two-dimensional bar code in the horizontal and vertical direction of information, information capacity is large, the structure is usually square structure, high security level, can directly display English, Chinese, numbers, symbols, graphs and so on.

A rendering of the ZBar component scanning a 2d barcode is shown in Figure 3. The scanning process is the same as the above one-dimensional bar code, and the status bar will display the scanning results of the TWO-DIMENSIONAL bar code.

Figure 3 Two-dimensional code scanning results

The Sample analysis

In the Sample part, the camera equipment is first created and reasonably configured, and then the original data obtained by the camera is transmitted to the Library for scanning processing. Finally, the scanning results are obtained and displayed on the screen. The following is a specific explanation of the code in Sample:

1. Generate Camera class objects

The CameraKit class can provide entries that use camera functionality, and the CameraStateCallbackImpl class is the callback for camera creation and camera runtime. The Camera object is generated by the CameraKit class. Unusually, the CameraKit class does not return the Camera object directly. Instead, the Camera object needs to be retrieved from the CameraStateCallbackImpl callback.

Private void openCamera(){// Get CameraKit object CameraKit = Camerakit. getInstance(this); if (cameraKit == null) { return; CameraIds String[] cameraIds = camerakit.getCameraids (); 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"); } // Create a thread for running the camera EventHandler EventHandler = new EventHandler(eventrunner.create (" camera B ")); if(eventHandler ==null) { System.out.println("eventHandler is null"); } // Create camerakit.createcamera (cameraIds[0], cameraStateCallback, eventHandler); } catch (IllegalStateException e) { System.out.println("getCameraIds fail"); }}Copy the code

2. Bind the camera Surface

The Surface is used to preview, take photos and record videos. Here add: previewSurface and dataSurface for the camera. The former shows the interface captured by the camera; The latter is used to read and process the data captured by the camera.

Private Final Class CameraStateCallbackImpl extends CameraStateCallback {// Callback for camera creation and camera runtime @override public void onCreated(Camera camera) { mcamera = camera; / / get to Camera object CameraConfig. The Builder cameraConfigBuilder = Camera. GetCameraConfigBuilder (); if (cameraConfigBuilder == null) { System.out.println("onCreated cameraConfigBuilder is null"); return; } / / configuration preview Surface cameraConfigBuilder. AddSurface (previewSurface); / / configuration process the data of Surface dataSurface = imageReceiver. GetRecevingSurface (); cameraConfigBuilder.addSurface(dataSurface); Try {/ camera/camera equipment configuration. The configure (cameraConfigBuilder. The build ()); } catch (IllegalArgumentException e) { System.out.println("Argument Exception"); } catch (IllegalStateException e) { System.out.println("State Exception"); }}}Copy the code

3. Enable loop frame capture

Users generally take photos or perform other operations after the picture is generated. With loop frame capture turned on, dataSurface can retrieve data from the camera.

@override public void onConfigured(Camera Camera) {// Get the template frameconfig. Builder frameConfigBuilder = mcamera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW); / / configuration preview Surface frameConfigBuilder. AddSurface (previewSurface); The pictures of the / / configuration Surface frameConfigBuilder. AddSurface (dataSurface); Try {/ / start loop frame capture int triggerId = McAmera. TriggerLoopingCapture (frameConfigBuilder. The build ()); } catch (IllegalArgumentException e) { System.out.println("Argument Exception"); } catch (IllegalStateException e) { System.out.println("State Exception"); }}Copy the code

4. Scan the camera data

The data in dataSurface is the original data of the camera in the format of YUV420, which needs to be encapsulated as the data of Image class to perform the formal scan of the incoming ImageScanner class.

/ / the camera raw data encapsulation for Image data Image barcode = new Image (mImage. GetImageSize (). The width, mImage. GetImageSize (). The height, "Y800"); barcode.setData(YUV_DATA); //Image data scan int result = scanner.scanimage (barcode);Copy the code

5. Display the scan results of preview data

Because there may be more than one bar code in the aligner and multiple scans for the ImageScanner class, the final scan result returned is of type SymbolSet. This data type is a container that can hold multiple symbols, each representing the scan result of a bar code.

// Create a container that can hold multiple Symbol data SymbolSet SymbolSet syms = scanner.getresults (); // Iterate over each element in SymbolSet for (Symbol sym: Syms) {handler.posttask (new Runnable() {@override public void run() {scantext.settext (" scan result :" + sym.getData()); // Get the information from Symbol scantext.invalidate (); }});Copy the code

The Library parsing

The Library part mainly scans the data of dataSurface, which mainly involves two functions :(1) the original data of the camera is encapsulated as Image data; (2) Scan Image data. Since this part is mainly implemented by C language, this part only analyzes the general principle and shows the main interface, and does not show the underlying code.

(1) The original data of the camera is encapsulated as Image data

Image supports a variety of data formats, including common YUV and RGB data. The Image data required here is of “Y800” type or “GRAY” type, that is, the scanning data of bar code only needs the GRAY data of the Image.

public native void setData(byte[] data);
Copy the code

(2) Scan Image data

The incoming Image data is scanned using the scanImage() method. In this process, the incoming image is firstly configured and verified, and then it is scanned in increments of one pixel point line by line, the scanning path is z-shaped, and the filtering of the scanned data is completed, the edge gradient is obtained, the gradient threshold is adaptive, the edge is determined, and finally the scanned data is transformed into the light and dark width stream. The type of bar code being scanned can be known by the changing pattern of the light and dark width flow, and then the bar code information can be obtained by decoding according to the fixed decoding method.

public native int scanImage(Image image);
Copy the code

Project contributor

Chen Congxiao zheng Senwen Zhu Wei Chen Mei Ru Zhang Xinxin

Author: Zhu Wei ISRC

For more information, visit Harmonyos.51cto.com, a collaboration between 51CTO and Huawei