Wechat scan how to judge the environment to show whether the light is on (guess)

At first, I thought it was when the light was dark, then I blocked the sensor, and I still didn't prompt to turn on the light after scanning the wechat, so I guess it should be judged with the brightness of the scanned object.
This function has been implemented, and the core principles are as follows:

Decode preview frame objects, including width and height

@param data   The YUV preview frame.
     * @param width  The width of the preview frame.
     * @param height The height of the preview frame.
decode((byte[]) message.obj, message.arg1, message.arg2);

Specific decoding process:

/**
     * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
     * reuse the same reader objects from one decode to the next.
     *
     * @param data   The YUV preview frame.
     * @param width  The width of the preview frame.
     * @param height The height of the preview frame.
     */
    private void decode(byte[] data, int width, int height) {
        long start = System.currentTimeMillis();
        Result rawResult = null;

        //modify here
        byte[] rotatedData = new byte[data.length];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++)
                rotatedData[x * height + height - y - 1] = data[x + y * width];
        }
        int tmp = width; // Here we are swapping, that's the difference to #11
        width = height;
        height = tmp;
        /**Increase the average color value of the camera image*/
        frameCount++;
        //Discard the first 2 frames and analyze the color value of preview frame every 2 frames
        if (frameCount > 2 && frameCount % 2 == 0) {
            analysisColor(rotatedData, width, height);
        }
        /********/

        PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        try {
            rawResult = multiFormatReader.decodeWithState(bitmap);
        } catch (ReaderException re) {
            // continue
        } finally {
            multiFormatReader.reset();
        }

        if (rawResult != null) {
            long end = System.currentTimeMillis();
            Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
            Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
            Bundle bundle = new Bundle();
            bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
            message.setData(bundle);
            //Log.d(TAG, "Sending decode succeeded message...");
            message.sendToTarget();
        } else {
            Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
            message.sendToTarget();
        }
    }

Analyze the rgb of the picture in the preview frame. Since the Bitmap generated at the beginning is the data of the whole frame, which is too large, select the Bitmap object with the center point width and height of 10 pixels to analyze Chengdu between the image and the pure black. After testing, select 80% of the black we think it is appropriate to turn on the light for scanning

/**Analyze the average value of rgb of pictures in preview frame*/
    private void analysisColor(byte[] data, int width, int height) {
        int[] rgb = decodeYUV420SP(data, width / 8, height / 8);
        Bitmap bmp = Bitmap.createBitmap(rgb, width / 8, height / 8, Bitmap.Config.ARGB_8888);
        if (bmp != null) {
            //Take a picture with center point width and height of 10 pixels for analysis
            Bitmap resizeBitmap = Bitmap.createBitmap(bmp, bmp.getWidth() / 2, bmp.getHeight() / 2, 10, 10);
            float color = (float) getAverageColor(resizeBitmap);
            DecimalFormat decimalFormat1 = new DecimalFormat("0.00");
            String percent = decimalFormat1.format(color / -16777216);
            float floatPercent = Float.parseFloat(percent);
            activity.isWeakLight = floatPercent >= 0.80 && floatPercent <= 1.00;
            if (null != resizeBitmap) {
                resizeBitmap.recycle();

            }
            bmp.recycle();
        }
    }

Posted on Thu, 26 Mar 2020 12:24:17 -0400 by NewBob