ZXing for ASP.NET MVC 扫描条码

Posted

技术标签:

【中文标题】ZXing for ASP.NET MVC 扫描条码【英文标题】:ZXing for ASP.NET MVC to scan barcodes 【发布时间】:2020-03-13 23:42:24 【问题描述】:

我正在寻找使用 ZXing 库和 ASP.NET MVC 来扫描条形码,我能够在 Xamarin.Forms 中执行此操作,现在尝试将相同的代码应用于 ASP.NET MVC 项目。在我的 Xamarin.Forms 中,我有以下内容:

            var options = new MobileBarcodeScanningOptions
            
                TryHarder = true,
                CameraResolutionSelector = HandleCameraResolutionSelectorDelegate,
                PossibleFormats = new List<BarcodeFormat>  BarcodeFormat.PDF_417 ,
            ;


            BarcodeScanView.Options = options;

            BarcodeScanView.IsVisible = true;
            BarcodeScanView.IsScanning = true;

我会有一个像这样的 onScan 方法:

public async void OnScanResult(Result result)


在我的 xaml 文件中,我有这样的 zxing 元素:

<zxing:ZXingScannerView x:Name="BarcodeScanView" IsVisible="false" HeightRequest="200" OnScanResult="OnScanResult" />

所以我的问题是在 ASP.NET 中与 this 等效的是什么,与此 zxing 元素等效的是什么?

请帮忙!

更新

我已经走的是相机使用jQuery和ZXing.NET调试PDF417条码的路线:

这是我的 html

<video id="video"  ></video>
<canvas id="canvas"  ></canvas>

以及用于相机的 jQuery 和调用 .NET 方法来调试条形码的代码:

var video = document.getElementById('video');

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) 


        navigator.mediaDevices.getUserMedia( video: true ).then(function (stream) 
            video.srcObject = stream;
            video.play();
        );
    

    $("#video").on("playing", function () 

        setInterval(function ()  scanBarcode() , 500);

    );

    function scanBarcode() 

        var video = document.getElementById('video');
        var canvas = document.getElementById('canvas');
        var canvas_context = canvas.getContext('2d');

        canvas_context.drawImage(video, 0, 0, 640, 480);

        var image = document.getElementById("canvas").toDataURL("image/png");

        image = image.replace('data:image/png;base64,', '');

        $.post("Home/OnScan",  imageData: image , function (data, status) 

            console.log(data);

        );

    

这是我调试 PDF417 条码的 .NET 方法:

public JsonResult OnScan(string imageData)
        

            BitmapImage bitmapImage = new BitmapImage();
            byte[] byteBuffer = Convert.FromBase64String(imageData);

            Bitmap bmp;
            using (var ms = new MemoryStream(byteBuffer))
            
                bmp = new Bitmap(ms);
            

            BarcodeReader reader = new BarcodeReader();

            DecodingOptions options = new DecodingOptions
            
                TryHarder = true,
                PossibleFormats = new List<BarcodeFormat>  BarcodeFormat.PDF_417 
            ;

            reader.Options = options;

            var result = reader.Decode(bmp);

            return Json(result.Text, JsonRequestBehavior.AllowGet);
        

现在这仍然不起作用,但我记得当我第一次在 Xamarin.Forms 中执行此操作时,它也不起作用,直到我添加 CameraResolutionSelector 选项:

var options = new MobileBarcodeScanningOptions
            
                TryHarder = true,
                CameraResolutionSelector = HandleCameraResolutionSelectorDelegate,
                PossibleFormats = new List<BarcodeFormat>  BarcodeFormat.PDF_417 ,
            ;

这里是 HandleCameraResolutionSelectorDelegate 方法:

public CameraResolution HandleCameraResolutionSelectorDelegate(List<CameraResolution> availableResolutions)
        
            //Don't know if this will ever be null or empty
            if (availableResolutions == null || availableResolutions.Count < 1)
                return new CameraResolution()  Width = 800, Height = 600 ;

            //Debugging revealed that the last element in the list
            //expresses the highest resolution. This could probably be more thorough.
            return availableResolutions[availableResolutions.Count - 1];
        

所以我开始认为是相机的分辨率导致我的条码无法扫描....另一方面,当我将 BarcodeFormat 更改为 QR_CODE 并扫描 QR 码时它可以工作,但不适用于 PDF417 条码...我做错了什么?

【问题讨论】:

您知道您的 Web 应用程序无法将附加到您的客户端的条形码扫描仪直接链接到服务器端代码吗? 我想,我只是想使用 ZXing 库来扫描我的 ASP.NET MVC 项目中的条形码....对 ZXing 很陌生,只是发现它在 Xamarin.Forms 中很容易使用 Xamarin.Forms 将在最终用户的计算机上运行,​​而不是在 Web 服务器上运行。你明白客户端代码和服务器端代码的区别吗? 是的,我愿意....我只是看看是否可以在 ASP.NET MVC 项目中使用 ZXing 库 即使可以,库也会在网络服务器上执行。因此,您需要在客户端运行一些部分,以获取条码的图像并将其发送到服务器。您需要对客户端服务器架构有深入的了解,将您的问题分解为小任务,并尝试完成每个任务。如果你被困在一个单独的任务上,那么你可能有一个有效的问题。 “帮我在 ASP.NET MVC 中使用这个库”不是一个有效的问题。 【参考方案1】:

正如我已经回答的here

我有一些类似这个问题的实例,在图像重建明显良好的情况下,zxing 无法按预期解码,我无法找出原因。

尝试输入PureBarcode = true 将解决问题。

DecodingOptions options = new DecodingOptions

    TryHarder = true,
    PossibleFormats = new List<BarcodeFormat>  BarcodeFormat.PDF_417 ,
    PureBarcode = true,
    AutoRotate = true,
    TryInverted = true,
    CameraResolutionSelector = HandleCameraResolutionSelectorDelegate
;

CameraResolution HandleCameraResolutionSelectorDelegate(List<CameraResolution> availableResolutions)

    if (availableResolutions == null || availableResolutions.Count < 1)
        return new CameraResolution ()  Width = 800, Height = 600 ;   
    return availableResolutions [availableResolutions.Count - 1];

此外,还有很多解码选项可以优化Decode,您可以将其用于解码。

namespace ZXing.Interop.Decoding

    /// <summary>
    /// Defines an container for encoder options
    /// </summary>
    [Serializable]
    [ComVisible(true)]
    [Guid("24BE4318-BF09-4542-945D-3A9BF1DF5682")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class DecodingOptions
    
        internal readonly ZXing.Common.DecodingOptions wrappedDecodingOptions;
        internal readonly BarcodeFormatCollection formatCollection;

        /// <summary>
        /// Gets or sets a flag which cause a deeper look into the bitmap
        /// </summary>
        /// <value>
        ///   <c>true</c> if [try harder]; otherwise, <c>false</c>.
        /// </value>
        public bool TryHarder
        
            get  return wrappedDecodingOptions.TryHarder; 
            set  wrappedDecodingOptions.TryHarder = value; 
        

        /// <summary>
        /// Image is a pure monochrome image of a barcode.
        /// </summary>
        /// <value>
        ///   <c>true</c> if monochrome image of a barcode; otherwise, <c>false</c>.
        /// </value>
        public bool PureBarcode
        
            get  return wrappedDecodingOptions.PureBarcode; 
            set  wrappedDecodingOptions.PureBarcode = value; 
        

        /// <summary>
        /// Specifies what character encoding to use when decoding, where applicable (type String)
        /// </summary>
        /// <value>
        /// The character set.
        /// </value>
        public string CharacterSet
        
            get  return wrappedDecodingOptions.CharacterSet; 
            set  wrappedDecodingOptions.CharacterSet = value; 
        

        /// <summary>
        /// Image is known to be of one of a few possible formats.
        /// Maps to a @link java.util.List of @link BarcodeFormats.
        /// </summary>
        /// <value>
        /// The possible formats.
        /// </value>
        public IBarcodeFormatCollection PossibleFormats
        
            get  return formatCollection; 
        

        /// <summary>
        /// if Code39 could be detected try to use extended mode for full ASCII character set
        /// </summary>
        public bool UseCode39ExtendedMode
        
            get  return wrappedDecodingOptions.UseCode39ExtendedMode; 
            set  wrappedDecodingOptions.UseCode39ExtendedMode = value; 
        

        /// <summary>
        /// Don't fail if a Code39 is detected but can't be decoded in extended mode.
        /// Return the raw Code39 result instead. Maps to <see cref="bool" />.
        /// </summary>
        public bool UseCode39RelaxedExtendedMode
        
            get  return wrappedDecodingOptions.UseCode39RelaxedExtendedMode; 
            set  wrappedDecodingOptions.UseCode39RelaxedExtendedMode = value; 
        

        /// <summary>
        /// Assume Code 39 codes employ a check digit. Maps to <see cref="bool" />.
        /// </summary>
        /// <value>
        ///   <c>true</c> if it should assume a Code 39 check digit; otherwise, <c>false</c>.
        /// </value>
        public bool AssumeCode39CheckDigit
        
            get  return wrappedDecodingOptions.AssumeCode39CheckDigit; 
            set  wrappedDecodingOptions.AssumeCode39CheckDigit = value; 
        

        /// <summary>
        /// If true, return the start and end digits in a Codabar barcode instead of stripping them. They
        /// are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
        /// to not be. Doesn't matter what it maps to; use <see cref="bool" />.
        /// </summary>
        public bool ReturnCodabarStartEnd
        
            get  return wrappedDecodingOptions.ReturnCodabarStartEnd; 
            set  wrappedDecodingOptions.ReturnCodabarStartEnd = value; 
        

        /// <summary>
        /// Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
        /// For example this affects FNC1 handling for Code 128 (aka GS1-128).
        /// </summary>
        /// <value>
        ///   <c>true</c> if it should assume GS1; otherwise, <c>false</c>.
        /// </value>
        public bool AssumeGS1
        
            get  return wrappedDecodingOptions.AssumeGS1; 
            set  wrappedDecodingOptions.AssumeGS1 = value; 
        

        /// <summary>
        /// Assume MSI codes employ a check digit. Maps to <see cref="bool" />.
        /// </summary>
        /// <value>
        ///   <c>true</c> if it should assume a MSI check digit; otherwise, <c>false</c>.
        /// </value>
        public bool AssumeMSICheckDigit
        
            get  return wrappedDecodingOptions.AssumeMSICheckDigit; 
            set  wrappedDecodingOptions.AssumeMSICheckDigit = value; 

        

        /// <summary>
        /// Allowed lengths of encoded data -- reject anything else. Maps to an int[].
        /// </summary>
        public int[] AllowedLengths
        
            get  return wrappedDecodingOptions.AllowedLengths; 
            set  wrappedDecodingOptions.AllowedLengths = value; 
        

        /// <summary>
        /// Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
        /// Maps to an int[] of the allowed extension lengths, for example [2], [5], or [2, 5].
        /// If it is optional to have an extension, do not set this hint. If this is set,
        /// and a UPC or EAN barcode is found but an extension is not, then no result will be returned
        /// at all.
        /// </summary>
        public int[] AllowedEANExtensions
        
            get  return wrappedDecodingOptions.AllowedEANExtensions; 
            set  wrappedDecodingOptions.AllowedEANExtensions = value; 
        

        /// <summary>
        /// Initializes a new instance of the <see cref="DecodingOptions"/> class.
        /// </summary>
        public DecodingOptions()
        
            wrappedDecodingOptions = new ZXing.Common.DecodingOptions();
            formatCollection = new BarcodeFormatCollection(wrappedDecodingOptions);
        

        internal DecodingOptions(ZXing.Common.DecodingOptions other)
        
            wrappedDecodingOptions = other;
            formatCollection = new BarcodeFormatCollection(wrappedDecodingOptions);
        
    

【讨论】:

PureBarcode 只能用于特殊场景。它仅适用于带有条形码的图像,其中代码本身周围只有一个白色区域。对于来自网络摄像头的真实图像,通常情况并非如此。 PureBarcode 在内部使用非常非常简单的逻辑来定位代码,该代码仅适用于由条形码写入器直接生成的合成图像。或者,如果您使用不同的检测器,则可以使用 PureBarcode,从原始图像中切出带有条形码的区域,并仅使用原始图像中的这一部分进行解码过程。

以上是关于ZXing for ASP.NET MVC 扫描条码的主要内容,如果未能解决你的问题,请参考以下文章

传输了几条消息后,ASP.NET MVC 4.5 WebSocket 服务器失去连接

如何只显示数据库中最近的 5 条记录 - ASP.NET MVC

从右到左 GridView For Asp.net MVC

在 ASP.Net MVC 应用程序中从 Facebook SDK for .Net 获取 Facebook 用户访问令牌

ASP.NET MVC:使用 Visual Studios for Mac 连接 SQL 数据库

有没有人为 ASP.NET MVC 实现 RadioButtonList For<T> ?