rhymelph / r_scan

📷🖨Flutter二维码&条形码扫描插件,支持相机、文件、链接、Uint8List类型扫描
https://juejin.im/post/5dd8efb1e51d452314438515
BSD 3-Clause "New" or "Revised" License
119 stars 79 forks source link

扫描二维码既快又准,但无法扫描条码 #14

Closed qinrunhao closed 4 years ago

qinrunhao commented 4 years ago

你好,看到类似问题,不知为什么关闭了,没找到解决方案。最新版的example无法扫描条码。

rhymelph commented 4 years ago

都是支持的,请换个角度进行扫码: 例如你的条形码



请换为

再次扫码

rhymelph commented 4 years ago

或者将手机横放扫码

qinrunhao commented 4 years ago

各种角度都试了,扫不到。然后看了源码,比如图片识别ImageScanHelper.java中,只使用了QRCodeReader识别二维码,不知是不是这个引起的?

rhymelph commented 4 years ago

好的,目前相机是支持的哦

rhymelph commented 4 years ago

QRCodeReader 这个问题,你可以自己尝试使用MultiFormatReader是否能扫码,如果能解决,欢迎pr

qinrunhao commented 4 years ago

试了MultiFormatReader,但不论是MultiFormatReader还是QRCodeReader,都存在一个问题,就是偶尔能扫描出来,大部分情况下都返回NotFoundException,应该是com.google.zxing内部的问题吧。这让我想起了很早之前微信、支付宝扫描图片都存在的一个现象,图片会不停的被放大或缩小,直到扫描出二维码和条码(很可能是为解决类似于NotFoundException才出现的情况)。现在微信、支付宝都没有这个现象了,不知道采取了什么措施。

qinrunhao commented 4 years ago

暂时解决安卓扫描条码问题,可横屏也可竖屏。需要修改RScanCamera.java

private synchronized void startPreviewWithImageStream()
            throws CameraAccessException {
        createCaptureSession(imageStreamReader.getSurface());

        imageStreamReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader imageReader) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        long currentTimestamp = System.currentTimeMillis();
                        if (currentTimestamp - lastCurrentTimestamp >= 1L && isPlay == Boolean.TRUE) {
                            Image image = imageReader.acquireLatestImage();
                            if (image == null) return;
                            if (ImageFormat.YUV_420_888 != image.getFormat()) {
                                Log.d(TAG, "analyze: " + image.getFormat());
                                return;
                            }
                            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                            byte[] array = new byte[buffer.remaining()];
                            buffer.get(array);
                            int height = image.getHeight();
                            int width = image.getWidth();
                            //优先图片翻转解析(主要解决习惯性竖屏扫条码问题,二维码不受影响)
                            PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(getRotatedData(array, width, height),
                                    height,
                                    width,
                                    0,
                                    0,
                                    height,
                                    width,
                                    true);
                            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
                            try {
                                final Result decode = reader.decode(binaryBitmap);
                                if (decode != null) {
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            rScanMessenger.send(decode);
                                        }
                                    });
                                }
                            } catch (NotFoundException e) {
                                //原图解析
                                source = new PlanarYUVLuminanceSource(array,
                                        width,
                                        height,
                                        0,
                                        0,
                                        width,
                                        height,
                                        false);
                                binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
                                try {
                                    final Result decode = reader.decode(binaryBitmap);
                                    if (decode != null) {
                                        handler.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                rScanMessenger.send(decode);
                                            }
                                        });
                                    }
                                } catch (Exception e1) {
                                    buffer.clear();
                                }
                            } catch (Exception e) {
                                buffer.clear();
                            }
                            lastCurrentTimestamp = currentTimestamp;
                            image.close();
                        }
                    }
                });
            }}, handler);
    }
gxh-apologize commented 4 years ago

@qinrunhao 请问这个方法getRotatedData是怎么实现的,我现在使用这个插件扫条形码需要竖着才行。

qinrunhao commented 4 years ago

@qinrunhao 请问这个方法getRotatedData是怎么实现的,我现在使用这个插件扫条形码需要竖着才行。

private byte[] getRotatedData(byte[] data, int width, int height) {
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];
}
return rotatedData;
}
gxh-apologize commented 4 years ago

@qinrunhao 好的,谢谢啦

masewo commented 4 years ago

Should be fixed with version 0.1.5 (?).

qinrunhao commented 4 years ago

@masewo Sorry! Maybe you could ask @rhymelph . I haven't been paying attention to this lately.