preface
Through the analysis of the last blog, we have clarified the general process of scanning code decoding, and learned how to obtain a frame of image data of the camera and carry out message transmission. This blog is used to analyze in detail how to perform specific image decoding processing after obtaining image data. The message processing sequence diagram is as follows:
First, let's take a look at the message object passed. The values of the parameters are:
parameter | Value |
---|---|
What (message ID) | R.id.decode |
Arg1 (integer parameter) | Width of camera resolution |
Arg2 (integer parameter) | Height of camera resolution |
Obj (transfer object) | byte[] data represents the data of the preview image |
1, Basic knowledge
2, Image decoding processing
First, let's take a look at the message object passed. The values of the parameters are:
parameter | Value |
---|---|
What (message ID) | R.id.decode |
Arg1 (integer parameter) | Width of camera resolution |
Arg2 (integer parameter) | Height of camera resolution |
Obj (transfer object) | byte[] data represents the data of the preview image |
1. DecodeHandler processes image decoding
Handle the message handleMessage sent from the child thread
Since the processor has been injected before, the sent message will be passed to the handleMessage method of decodehandler
public void handleMessage(Message message) { if (message == null || !running) { return; } // Cancel information identification header switch (message.what) { case R.id.decode: // Call the decode method decode((byte[]) message.obj, message.arg1, message.arg2); break; case R.id.quit: running = false; Looper.myLooper().quit(); break; } }
If the corresponding message ID header here is' R.id.decode ', call the DecodeHandler's decode method. Let's take a look at this method
decode image
private void decode(byte[] data, int width, int height) { // Decoding result returned Result rawResult = null; // Convert the YUV data array returned from the camera device, and you can selectively cut the complete YUV data, part of which can be used for parsing, so as to speed up the speed PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height); if (source != null) { // Mix and binarize the picture to create a binarized bit bitmap BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); try { // Call the core algorithm and return the decoding result rawR,esult = multiFormatReader.decodeWithState(bitmap); } catch (ReaderException re) { } finally { multiFormatReader.reset(); } } Handler handler = activity.getHandler(); if (rawResult != null) { if (handler != null) { // Create and send a successfully decoded message Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult); Bundle bundle = new Bundle(); bundleThumbnail(source, bundle); message.setData(bundle); message.sendToTarget(); } } else { if (handler != null) { // Create and send a message that failed decoding Message message = Message.obtain(handler, R.id.decode_failed); message.sendToTarget(); } } }
From the analysis, the decode method of DecodeHandler mainly completes the following actions:
- Firstly, the PlanarYUVLuminanceSource object is instantiated. Its main function is to clip the incoming image data and remove the parts outside the scan frame to speed up the decoding speed.
- Then the picture is binarized and assigned to a binary bit bitmap
- Pass in the binary bitmap, call the decoding algorithm of core.jar, and return the decoding result
- Send the message of successful decoding (failure). The receiver should be CaptureActivityHandler