user979331
user979331

Reputation: 11931

ZXing.NET decode PDF417 Barcode from HTML5 Video

I am trying to use jQuery/JavaScript with ZXing.NET to decode a PDF417 barcode from a video source.

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) {
    const hdConstraints = {
        video: { width: { min: 1280 }, height: { min: 720 } }
    };

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

As you can see there I am getting the image of the canvas and passing it to my .NET method.

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?

Upvotes: 4

Views: 2569

Answers (1)

Vignesh Kumar A
Vignesh Kumar A

Reputation: 28413

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

Upvotes: 1

Related Questions