简体   繁体   English

使用 Zxing 读取 Xamarin 表单中的二维码

[英]Reading QR code in Xamarin Forms With Zxing

I am trying to import a QR code from a .png file and decode it using Zxing.Net.Mobile and ZXing.Net.Mobile.Forms .我正在尝试从.png 文件导入二维码并使用Zxing.Net.MobileZXing.Net.Mobile.Forms对其进行解码。

If I scan the QR code using the ZXing.Mobile.MobileBarcodeScanner class, the decoding works as required, however, when importing it from a file, the Qr code reader ( ZXing.QrCode.QRCodeReader() ) decode function always returns null .如果我使用ZXing.Mobile.MobileBarcodeScanner类扫描二维码,解码会按要求工作,但是,从文件导入时, ZXing.QrCode.QRCodeReader()码阅读器 ( ZXing.QrCode.QRCodeReader() ) 解码函数始终返回null

As I'm using Xamarin Forms ;当我使用Xamarin Forms 时 each platform handles the bitmap/image creation and the portable part handle the rest ( Zxing BinaryBitmap creation and decoding).每个平台处理位图/图像创建,可移植部分处理其余部分( Zxing BinaryBitmap创建和解码)。

//Store rawBytes and image demensions
PotableBitmap bMap = DependencyService.Get<IBitmap>().FileToBitmap(filePath);

RGBLuminanceSource source = new RGBLuminanceSource(bMap.RgbBytes, bMap.Width, bMap.Height, RGBLuminanceSource.BitmapFormat.RGB32);
HybridBinarizer binarized = new HybridBinarizer(source);
BinaryBitmap bitmap = new BinaryBitmap(binarized);
var reader = new ZXing.QrCode.QRCodeReader();
data = reader.decode(qrCodeBitmap); // This is always null

The DependencyService will call the platform specific function, at the moment I am working with Andorid so, the function is as follows: DependencyService会调用平台特定的函数,目前我正在使用 Andorid 所以,函数如下:

public PortableBitmap FileToBitmap(string ms)
{
    var bytes = File.ReadAllBytes(ms);
    Android.Graphics.Bitmap bMap = BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length);

    int[] intArray = new int[bMap.Width * bMap.Height];
    bMap.GetPixels(intArray, 0, bMap.Width, 0, 0, bMap.Width, bMap.Height)

    List<byte> result = new List<byte>();
    foreach (int intRgb in intArray)
    {
        Color pixelColor = new Color(intRgb);
        result.Add(pixelColor.R);
        result.Add(pixelColor.G);
        result.Add(pixelColor.B);
    }

    return new PortableBitmap(result.ToArray(), bMap.Width, bMap.Height);
}

I have looked through some of the posts on SO that are having the same problem and have tried the following:我浏览了一些关于 SO 的帖子,这些帖子有同样的问题,并尝试了以下方法:

  • Using BitmapLuminanceSource : still returns null and requires the use of another library使用BitmapLuminanceSource :仍然返回null并需要使用另一个库
  • Using different bitmap formats for the RGBLuminanceSource : RGB32, BGR32, ARGB32, ABGR32 (each time changing the FileToBitmap function)RGBLuminanceSource使用不同的位图格式:RGB32、BGR32、ARGB32、ABGR32(每次更改 FileToBitmap 函数)
  • Tried the different Binarizer , GlobalHistogramBinarizer()尝试了不同的BinarizerGlobalHistogramBinarizer()
  • Checked that the file is being read correctly by reading and wrinting it back to a file.通过读取文件并将其写回文件来检查文件是否被正确读取。
  • I have tried using the MultiFormatReader() with the Pure barcode and try harder hints我曾尝试将MultiFormatReader()与 Pure 条码一起使用,并尝试更难的提示
  • I have also debugged the libraries source code and from what I understand it just can't find the QR code in the imported image.我还调试了库源代码,据我所知,它在导入的图像中找不到二维码。 No exception is thrown.不会抛出任何异常。

Here is where the return null is made:这是返回null地方:

private FinderPattern[] selectBestPatterns()
    {
        int startSize = possibleCenters.Count;
        if (startSize < 3)
        {
            // Couldn't find enough finder patterns
            return null; // It returns here
        }
        ...

The online Zxing decoder can decode the QR code I'm testing correctly.在线Zxing解码器可以正确解码我正在测试的二维码。 Here is my test QR code:这是我的测试二维码:

我的二维码图片

I solved that problem, with this method in the Android implementation to return an RGBLuminanceSource from the path of the image我解决了这个问题,在Android实现中使用这个方法从图像的路径返回一个RGBLuminanceSource

    public RGBLuminanceSource GetRGBLuminanceSource(string imagePath)
    {
        if (File.Exists(imagePath))
        {
            Bitmap bitmap = BitmapFactory.DecodeFile(imagePath);
            List<byte> rgbBytesList = new List<byte>();
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    var c = new Color(bitmap.GetPixel(x, y));
                    rgbBytesList.AddRange(new[] { c.A, c.R, c.G, c.B });
                }
            }
            byte[] rgbBytes = rgbBytesList.ToArray();
            return new RGBLuminanceSource(rgbBytes, bitmap.Height, bitmap.Width, RGBLuminanceSource.BitmapFormat.ARGB32);
        }
        return null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM