ZXing for ASP.NET MVC 扫描条码 [英] ZXing for ASP.NET MVC to scan barcodes

查看:54
本文介绍了ZXing for ASP.NET MVC 扫描条码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 var options = new MobileBarcodeScanningOptions{TryHarder = 真,CameraResolutionSelector = HandleCameraResolutionSelectorDelegate,可能的格式 = 新列表{ BarcodeFormat.PDF_417 },};BarcodeScanView.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" width="800" height="800"></video><canvas id="canvas" width="800" height="800"></canvas>

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

var video = document.getElementById('video');如果(navigator.mediaDevices && navigator.mediaDevices.getUserMedia){navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {video.srcObject = 流;视频播放();});}$("#video").on("播放", function () {setInterval(function () { scanBarcode() }, 500);});函数 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) {控制台日志(数据);});}

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

public JsonResult OnScan(string imageData){BitmapImage bitmapImage = new BitmapImage();byte[] byteBuffer = Convert.FromBase64String(imageData);位图 bmp;使用 (var ms = new MemoryStream(byteBuffer)){bmp = 新位图(毫秒);}BarcodeReader reader = new BarcodeReader();DecodingOptions 选项 = 新的 DecodingOptions{TryHarder = 真,可能的格式 = 新列表{ BarcodeFormat.PDF_417 }};reader.Options = 选项;var 结果 = reader.Decode(bmp);返回 Json(result.Text, JsonRequestBehavior.AllowGet);}

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

var options = new MobileBarcodeScanningOptions{TryHarder = 真,CameraResolutionSelector = HandleCameraResolutionSelectorDelegate,可能的格式 = 新列表{ BarcodeFormat.PDF_417 },};

这是 HandleCameraResolutionSelectorDelegate 方法:

public CameraResolution HandleCameraResolutionSelectorDelegate(ListavailableResolutions){//不知道这是否会为空或空if (availableResolutions == null || availableResolutions.Count <1)返回新的 CameraResolution() { 宽度 = 800,高度 = 600 };//调试发现列表中的最后一个元素//表示最高分辨率.这可能会更彻底.返回 availableResolutions[availableResolutions.Count - 1];}

所以我开始认为是相机的分辨率导致我的条形码无法扫描....另外,当我将 BarcodeFormat 更改为 QR_CODE 并扫描它可以工作的二维码时,但不能使用 PDF417 条形码...我做错了什么?

解决方案

我已经回答了这里

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

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

DecodingOptions 选项 = 新的 DecodingOptions{TryHarder = 真,可能的格式 = 新列表{ BarcodeFormat.PDF_417 },PureBarcode = 真,自动旋转 = 真,TryInverted = 真,CameraResolutionSelector = HandleCameraResolutionSelectorDelegate};CameraResolution HandleCameraResolutionSelectorDelegate(ListavailableResolutions){if (availableResolutions == null || availableResolutions.Count <1)返回新的 CameraResolution () { 宽度 = 800,高度 = 600 };返回 availableResolutions [availableResolutions.Count - 1];}

此外,有很多解码选项可以优化您可以用于解码的Decode.

命名空间 ZXing.Interop.Decoding{///<总结>///定义编码器选项的容器///</总结>[可序列化][ComVisible(true)][指南(24BE4318-BF09-4542-945D-3A9BF1DF5682")][ClassInterface(ClassInterfaceType.AutoDual)]公共类 DecodingOptions{内部只读 ZXing.Common.DecodingOptionswrappedDecodingOptions;内部只读 BarcodeFormatCollection formatCollection;///<总结>///获取或设置一个标志,导致更深入地查看位图///</总结>///<值>///<c>真</c>如果[努力];否则,<c>false</c>.///public bool TryHarder{得到 { 返回wrappedDecodingOptions.TryHarder;}设置 {wrappedDecodingOptions.TryHarder = 值;}}///<总结>///图像是条码的纯单色图像.///</总结>///<值>///<c>真</c>如果条形码的单色图像;否则,<c>false</c>.///public bool PureBarcode{得到 { 返回wrappedDecodingOptions.PureBarcode;}设置 {wrappedDecodingOptions.PureBarcode = 值;}}///<总结>///指定解码时使用的字符编码,如果适用(类型字符串)///</总结>///<值>///字符集.///公共字符串字符集{得到 { 返回wrappedDecodingOptions.CharacterSet;}设置 {wrappedDecodingOptions.CharacterSet = 值;}}///<总结>///已知图像是几种可能的格式之一.///映射到 {@link BarcodeFormat} 的 {@link java.util.List}.///</总结>///<值>///可能的格式.///公共 IBarcodeFormatCollection 可能的格式{得到 { 返回格式集合;}}///<总结>///如果可以检测到 Code39,请尝试对完整 ASCII 字符集使用扩展模式///</总结>public bool UseCode39ExtendedMode{得到 { 返回wrappedDecodingOptions.UseCode39ExtendedMode;}设置 {wrappedDecodingOptions.UseCode39ExtendedMode = value;}}///<总结>///如果检测到 Code39 但无法在扩展模式下解码,请不要失败.///返回原始 Code39 结果.映射到 <see cref="bool"/>.///</总结>public bool UseCode39RelaxedExtendedMode{得到 { 返回wrappedDecodingOptions.UseCode39RelaxedExtendedMode;}设置 {wrappedDecodingOptions.UseCode39RelaxedExtendedMode = value;}}///<总结>///假设 Code 39 代码使用校验位.映射到 <see cref="bool"/>.///</总结>///<值>///<c>真</c>如果它应该采用 Code 39 校验位;否则,<c>false</c>.///public bool AssumeCode39CheckDigit{得到 { 返回wrappedDecodingOptions.AssumeCode39CheckDigit;}设置 {wrappedDecodingOptions.AssumeCode39CheckDigit = value;}}///<总结>///如果为 true,则返回 Codabar 条码中的开始和结束数字,而不是将它们剥离.他们///是 alpha,而其余的是数字.默认情况下,它们会被剥离,但这会导致它们///不是.它映射到什么并不重要;使用 <see cref="bool"/>.///</总结>public bool ReturnCodabarStartEnd{得到 { 返回wrappedDecodingOptions.ReturnCodabarStartEnd;}设置{wrappedDecodingOptions.ReturnCodabarStartEnd = value;}}///<总结>///假设条形码被处理为 GS1 条形码,并根据需要修改行为.///例如,这会影响代码 128(又名 GS1-128)的 FNC1 处理.///</总结>///<值>///<c>真</c>如果它应该假设 GS1;否则,<c>false</c>.///公共布尔假设GS1{得到 { 返回wrappedDecodingOptions.AssumeGS1;}设置 {wrappedDecodingOptions.AssumeGS1 = value;}}///<总结>///假设 MSI 代码使用校验位.映射到 <see cref="bool"/>.///</总结>///<值>///<c>真</c>如果它应该假设一个 MSI 校验位;否则,<c>false</c>.///公共布尔假设MSICheckDigit{得到 { 返回wrappedDecodingOptions.AssumeMSICheckDigit;}设置{wrappedDecodingOptions.AssumeMSICheckDigit = value;}}///<总结>///允许的编码数据长度——拒绝任何其他内容.映射到 int[].///</总结>public int[] AllowedLengths{得到 { 返回wrappedDecodingOptions.AllowedLengths;}设置 {wrappedDecodingOptions.AllowedLengths = value;}}///<总结>///EAN 或 UPC 条形码允许的扩展长度.其他格式将忽略这一点.///映射到允许扩展长度的 int[],例如 [2]、[5] 或 [2, 5].///如果有扩展名是可选的,不要设置这个提示.如果这样设置,///并且找到了 UPC 或 EAN 条码但没有找到扩展名,则不会返回任何结果///根本没有.///</总结>public int[] AllowedEANExtensions{得到 { 返回wrappedDecodingOptions.AllowedEANExtensions;}设置 {wrappedDecodingOptions.AllowedEANExtensions = 值;}}///<总结>///初始化 <see cref="DecodingOptions"/> 的新实例班级.///</总结>公共解码选项(){WrappedDecodingOptions = new ZXing.Common.DecodingOptions();formatCollection = new BarcodeFormatCollection(wrappedDecodingOptions);}内部解码选项(ZXing.Common.DecodingOptions 其他){包裹解码选项 = 其他;formatCollection = new BarcodeFormatCollection(wrappedDecodingOptions);}}

I am looking for away to use to use the ZXing library with ASP.NET MVC to scan barcodes, I was able to do this in Xamarin.Forms and now trying to apply the same code to an ASP.NET MVC project. In my Xamarin.Forms I had the following:

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


            BarcodeScanView.Options = options;

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

and I would have an onScan method like so:

public async void OnScanResult(Result result)
{
}

and in my xaml file I had the zxing element like so:

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

So my question is what would be the equivalent to this in ASP.NET, what would be the equivalent to this zxing element?

Please Help!

UPDATE

I have gone the route of using jQuery for the camera and ZXing.NET to debug the PDF417 Barcode:

Here is my HTML:

<video id="video" width="800" height="800"></video>
<canvas id="canvas" width="800" height="800"></canvas>

And the jQuery for the camera and the code that calls an .NET method to debug the barcode:

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);

        });

    }

And here is my .NET method to debug the PDF417 barcode:

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);
        }

Now this still does not work, but I remembered when I first did this in Xamarin.Forms it also did not work until I add the CameraResolutionSelector option:

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

Here is the HandleCameraResolutionSelectorDelegate method:

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];
        }

So I am starting to think it the resolution of the camera that is causing my barcode not to scan....on another note when I change BarcodeFormat to QR_CODE and scan a QR code it works, but not with a PDF417 Barcode...what am I doing wrong?

解决方案

As I have have answered already here

I have some instances like the one of this issue, where with an apparently good image reconstruction, zxing can't decode as expected and i'm not competent to figure out why.

Try putting PureBarcode = true will resolve the issue.

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];
}

Also, There are lot of Decoding options to optimize the Decode which you can use for decoding.

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 BarcodeFormat}s.
        /// </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);
        }
    }

这篇关于ZXing for ASP.NET MVC 扫描条码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆