Yusril Maulidan Raji Yusril Maulidan Raji - 28 days ago 11
ASP.NET (C#) Question

Scan the QR code picture directly from camera with ZXing

I developed a ASP website (the target is for mobile users) with the main functionality to decode the QR code. I decided to use ZXing as the decoder and if I input the good image of QR code, it works perfectly. But when I change the source of the QR code by taking the picture directly from the camera with:

<input type="file" name="file" capture="camera" accept="image/*" id="cameraInput" name="cameraInput">


It doesn't work. Even though I take the picture as stable as I can, ZXing still cannot decode that picture from the camera.
The question is do you know what is the best way to decode QR code that is taken from camera? If this will take a lot of effort, then do you any other suggestion for decoding QR code (with the web platform of ASP.NET).

Answer

So, I already have the solution. In fact, the problem is not with the ZXing, but with the result of the taken image. Because when I try to take the image, and directly convert and show it into canvas, the result of the picture is tremendous big. That is why ZXing failed to decode it. But when I try to manage the canvas image first (to be 400 x 400 px in my case), send the base64 image to the server, convert it into image again in the server, and decode it. It works perfect like a charm.

Edited: Here is the code that I used for the solution (in order to make it readable, I remove some unrelated code. hopefully I didn't remove the useful part though)

var JsIndexPage = new function (jsonData) {
    this.pageData = {
        maxWidth: 400,
        maxHeight: 400
    };

    this.pageUI = {
        canvas: null,
        blankCanvas: null,
        messageDiv: null,
        cameraInput: null,
        uploadInput: null
    };

    this.initUI = function () {
        ///<summary>
        ///Display ui on the page
        ///</summary>

        this.pageUI.canvas = document.getElementById('capturedPhoto');
        this.pageUI.blankCanvas = document.getElementById('blank');
        this.pageUI.cameraInput = $('#cameraInput');
        this.pageUI.messageDiv = $("#message");
        this.pageUI.uploadInput = $('#uploadInput');

        //add triggers to buttons
        this.pageUI.cameraInput.on('change', function (e) {
            JsIndexPage.onCameraInputChanged(e);
        });

        this.pageUI.uploadInput.on('click', function () {
            JsIndexPage.onUploadInputClick();
        });
    };

    this.onCameraInputChanged = function (e) {
        /// <summary>
        /// On camera input changed write image to canvas
        /// </summary>

        var reader = new FileReader();
        reader.onload = function (event) {
            JsIndexPage.onFileSelected(event);
        }

        //contains the data as a URL representing the file's data as a base64 encoded string
        reader.readAsDataURL(e.target.files[0]);
    };

    this.onFileSelected = function (event) {
        ///<summary>
        /// Html5 file readed onLoad event handler
        ///</summary>

        var context = this.pageUI.canvas.getContext('2d');

        //instantiates the Image() object
        var img = new Image();
        img.onload = function () {

            //converts the sizes of image into the proper size (400 x 400 at maximum)
            if (img.width > JsIndexPage.pageData.maxWidth && img.height <= JsIndexPage.pageData.maxHeight) {
                JsIndexPage.pageUI.canvas.width = JsIndexPage.pageUI.maxWidth;
                JsIndexPage.pageUI.canvas.height = (JsIndexPage.pageUI.canvas.width / img.width) * img.height;
            }
            else if (img.width <= JsIndexPage.pageData.maxWidth && img.height > JsIndexPage.pageData.maxHeight) {
                JsIndexPage.pageUI.canvas.height = JsIndexPage.pageData.maxHeight;
                JsIndexPage.pageUI.canvas.width = (JsIndexPage.pageUI.canvas.height / img.height) * img.width;
            }
            else if (img.width <= JsIndexPage.pageData.maxWidth && img.height <= JsIndexPage.pageData.maxHeight) {
                JsIndexPage.pageUI.canvas.width = img.width;
                JsIndexPage.pageUI.canvas.height = img.height;
            }
            else if (img.width > JsIndexPage.pageData.maxWidth && img.height > JsIndexPage.pageData.maxHeight) {
                if (img.width > img.height) {
                    JsIndexPage.pageUI.canvas.width = JsIndexPage.pageData.maxWidth;
                    JsIndexPage.pageUI.canvas.height = (JsIndexPage.pageUI.canvas.width / img.width) * img.height;
                }
                else {
                    JsIndexPage.pageUI.canvas.height = JsIndexPage.pageData.maxHeight;
                    JsIndexPage.pageUI.canvas.width = (JsIndexPage.pageUI.canvas.height / img.height) * img.width;
                }
            }

            //draws the context to the canvas
            context.drawImage(img, 0, 0, JsIndexPage.pageUI.canvas.width, JsIndexPage.pageUI.canvas.height);
        }

        //changes the image source into the new one
        img.src = event.target.result;
    };
}