locked
Automatic QR Code Scanning RRS feed

  • Question

  • User-1994446809 posted

    Hello,

    I built a website for a school project, which will read QR codes. I used installed ByteScout SDK in the project and used the sample codes provided by Bytescout in the project but I want to achieve something different. The website I built can read the code but you have to click a button for it to scan and read. Also, the output result is shown in a textbox on the page.

    But please I want the website to automatically read QR code and automatically redirect to the address or information embedded in the QR code, instead of clicking a button and displaying the result in a textbox. I have inserted below this message, the codes I used in the project. I need help to see if these codes can be edited to make the webcamera read the QR code and redirect someone to whatever information is embedded in the QR.  I look forward to getting a solution please. Thank you very much.

    Default.aspx.cs
    
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
     
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
     
        }
    }
    FlashCamera.aspx.cs
    
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.IO; //For MemoryStream
    using System.Web.Services; //For WebMethod attribute
    using Bytescout.BarCodeReader;
    using System.Web.UI.HtmlControls;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Threading;
     
    public partial class uploadimage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
     
            try
            {
                String send = "";
                System.Drawing.Image originalimg;
                // read barcode type set 
                String type = Request.QueryString["type"].ToString();
                MemoryStream log = new MemoryStream();
                byte[] buffer = new byte[1024];
                int c;
                // read input buffer with image and saving into the "log" memory stream
                while ((c = Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    log.Write(buffer, 0, c);
                }
                // create image object
                originalimg = System.Drawing.Image.FromStream(log);
                // resample image
                originalimg = originalimg.GetThumbnailImage(640, 480, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
                Bitmap bp = new Bitmap(originalimg);
                // create bytescout barcode reader object
                Reader reader = new Reader();
                // set barcode type to read
                reader.BarcodeTypesToFind = GetBarcodeTypeToFindFromCombobox(type);
                // read barcodes from image
                reader.ReadFrom(bp);
                // if there are any result then convert them into a single stream
                if (reader.FoundBarcodes != null)
                {
                    foreach (FoundBarcode barcode in reader.FoundBarcodes)
                    {
                        // form the output string
                        send = send + (String.Format("{0} : {1}", barcode.Type, barcode.Value));
                    }
                }
                // close the memory stream
                log.Close();
                // dispose the image object
                originalimg.Dispose();
                // write output 
                Response.Write("<d>" + send + "</d>");
            }
            catch (Exception ex)
            {
                // write the exception if any
                Response.Write("<d>" + ex + "</d>");
            }
        }
        public bool ThumbnailCallback() { return false; }
     
        /// <summary>
        /// Get symbology filter for the SDK from the combobox selection text
        /// </summary>
        /// <param name="barType"></param>
        /// <returns></returns>
        private static BarcodeTypeSelector GetBarcodeTypeToFindFromCombobox(string barType)
        {
            string selectedItemText = barType.Trim().ToUpper();
            BarcodeTypeSelector barcodeTypeToScan = new BarcodeTypeSelector();
     
            if (selectedItemText.IndexOf("ALL BARCODES") > -1)
                barcodeTypeToScan.SetAll();
            else if (selectedItemText.IndexOf("ALL LINEAR BARCODES") > -1)
                barcodeTypeToScan.SetAll1D();
            else if (selectedItemText.IndexOf("ALL 2D BARCODES") > -1)
                barcodeTypeToScan.SetAll2D();
            else if (selectedItemText.IndexOf("AZTEC") > -1)
                barcodeTypeToScan.Aztec = true;
            else if (selectedItemText.IndexOf("CODABAR") > -1)
                barcodeTypeToScan.Codabar = true;
            else if (selectedItemText.IndexOf("CODE 39") > -1)
                barcodeTypeToScan.Code39 = true;
            else if (selectedItemText.IndexOf("CODE 128") > -1)
                barcodeTypeToScan.Code128 = true;
            else if (selectedItemText.IndexOf("DATAMATRIX") > -1)
                barcodeTypeToScan.DataMatrix = true;
            else if (selectedItemText.IndexOf("EAN 13") > -1)
                barcodeTypeToScan.EAN13 = true;
            else if (selectedItemText.IndexOf("GS1-128") > -1)
                barcodeTypeToScan.GS1 = true;
            else if (selectedItemText.IndexOf("GS1DATABAREXPANDED") > -1)
                barcodeTypeToScan.GS1DataBarExpanded = true;
            else if (selectedItemText.IndexOf("GS1DATABAREXPANDEDSTACKED") > -1)
                barcodeTypeToScan.GS1DataBarExpandedStacked = true;
            else if (selectedItemText.IndexOf("GS1DATABARLIMITED") > -1)
                barcodeTypeToScan.GS1DataBarLimited = true;
            else if (selectedItemText.IndexOf("GS1DATABAROMNIDIRECTIONAL") > -1)
                barcodeTypeToScan.GS1DataBarOmnidirectional = true;
            else if (selectedItemText.IndexOf("GS1DATABARSTACKED") > -1)
                barcodeTypeToScan.GS1DataBarStacked = true;
            else if (selectedItemText.IndexOf("I2OF5") > -1)
                barcodeTypeToScan.Interleaved2of5 = true;
            else if (selectedItemText.IndexOf("PATCH") > -1)
                barcodeTypeToScan.PatchCode = true;
            else if (selectedItemText.IndexOf("PDF 417") > -1)
                barcodeTypeToScan.PDF417 = true;
            else if (selectedItemText.IndexOf("QR CODE") > -1)
                barcodeTypeToScan.QRCode = true;
            else if (selectedItemText.IndexOf("UPCA") > -1)
                barcodeTypeToScan.UPCA = true;
            else if (selectedItemText.IndexOf("UPCE") > -1)
                barcodeTypeToScan.UPCE = true;
            else if (selectedItemText.IndexOf("MAXICODE") > -1)
                barcodeTypeToScan.MaxiCode = true;
     
            return barcodeTypeToScan;
        }
    }
    HTML5Camera.aspx.cs
    
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.IO; //For MemoryStream
    using System.Web.Services; //For WebMethod attribute
    using Bytescout.BarCodeReader;
    using System.Web.UI.HtmlControls;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Threading;
    using System.Text;
     
     
    public partial class Camera : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
     
        /// <summary>
        /// Takes the base64 encoded image from the browser
        /// and tries to read barodes from it
        /// </summary>
        /// <param name="image"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [WebMethod]
        public static string Upload(string image, string type)
        {
     
            try
            {
                StringBuilder send = new StringBuilder();
                // lock by send variable 
                lock (send)
                {            
                    // convert base64 string from the client side into byte array
                    byte[] bitmapArrayOfBytes = Convert.FromBase64String(image);
                    // convert the byte array into the bitmap 
                    Bitmap bp = (Bitmap)Bitmap.FromStream(new MemoryStream(bitmapArrayOfBytes));
                    // new bytescout barcode reader sdk object
                    Reader reader = new Reader();
                    // get the type to find from user's selection in the combobox
                    reader.BarcodeTypesToFind = GetBarcodeTypeToFindFromCombobox(type);
                    // read image to get barcodes
                    reader.ReadFrom(bp);
                    // check if we have got barcodes from the image
                    if (reader.FoundBarcodes != null)
                    {
                        // add each barcode into the string 
                        foreach (FoundBarcode barcode in reader.FoundBarcodes)
                        {
                            // add barcodes as text into the output string
                            send.AppendLine(String.Format("{0} : {1}", barcode.Type, barcode.Value));
                        }
                    }
                    // return the output string
                    return send.ToString();
                } // end of lock
            }
            catch (Exception ex)
            {
                // return the exception instead
                return (ex.Message + "\r\n" + ex.StackTrace);
            }
     
     
        }
        /// <summary>
        /// Get symbology filter for the SDK from the combobox selection text
        /// </summary>
        /// <param name="barType"></param>
        /// <returns></returns>
        private static BarcodeTypeSelector GetBarcodeTypeToFindFromCombobox(string barType)
        {
            string selectedItemText = barType.Trim().ToUpper();
            BarcodeTypeSelector barcodeTypeToScan = new BarcodeTypeSelector();
     
            if (selectedItemText.IndexOf("ALL BARCODES") > -1)
                barcodeTypeToScan.SetAll();
            else if (selectedItemText.IndexOf("ALL LINEAR BARCODES") > -1)
                barcodeTypeToScan.SetAll1D();
            else if (selectedItemText.IndexOf("ALL 2D BARCODES") > -1)
                barcodeTypeToScan.SetAll2D();
            else if (selectedItemText.IndexOf("AZTEC") > -1)
                barcodeTypeToScan.Aztec = true;
            else if (selectedItemText.IndexOf("CODABAR") > -1)
                barcodeTypeToScan.Codabar = true;
            else if (selectedItemText.IndexOf("CODE 39") > -1)
                barcodeTypeToScan.Code39 = true;
            else if (selectedItemText.IndexOf("CODE 128") > -1)
                barcodeTypeToScan.Code128 = true;
            else if (selectedItemText.IndexOf("DATAMATRIX") > -1)
                barcodeTypeToScan.DataMatrix = true;
            else if (selectedItemText.IndexOf("EAN 13") > -1)
                barcodeTypeToScan.EAN13 = true;
            else if (selectedItemText.IndexOf("GS1-128") > -1)
                barcodeTypeToScan.GS1 = true;
            else if (selectedItemText.IndexOf("GS1DATABAREXPANDED") > -1)
                barcodeTypeToScan.GS1DataBarExpanded = true;
            else if (selectedItemText.IndexOf("GS1DATABAREXPANDEDSTACKED") > -1)
                barcodeTypeToScan.GS1DataBarExpandedStacked = true;
            else if (selectedItemText.IndexOf("GS1DATABARLIMITED") > -1)
                barcodeTypeToScan.GS1DataBarLimited = true;
            else if (selectedItemText.IndexOf("GS1DATABAROMNIDIRECTIONAL") > -1)
                barcodeTypeToScan.GS1DataBarOmnidirectional = true;
            else if (selectedItemText.IndexOf("GS1DATABARSTACKED") > -1)
                barcodeTypeToScan.GS1DataBarStacked = true;
            else if (selectedItemText.IndexOf("I2OF5") > -1)
                barcodeTypeToScan.Interleaved2of5 = true;
            else if (selectedItemText.IndexOf("PATCH") > -1)
                barcodeTypeToScan.PatchCode = true;
            else if (selectedItemText.IndexOf("PDF 417") > -1)
                barcodeTypeToScan.PDF417 = true;
            else if (selectedItemText.IndexOf("QR CODE") > -1)
                barcodeTypeToScan.QRCode = true;
            else if (selectedItemText.IndexOf("UPCA") > -1)
                barcodeTypeToScan.UPCA = true;
            else if (selectedItemText.IndexOf("UPCE") > -1)
                barcodeTypeToScan.UPCE = true;
            else if (selectedItemText.IndexOf("MAXICODE") > -1)
                barcodeTypeToScan.MaxiCode = true;
     
            return barcodeTypeToScan;
        }
     
     
    }
    webcam.js
    
    
    /* JPEGCam v1.0.9 */
    /* Webcam library for capturing JPEG images and submitting to a server */
    /* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */
    /* Licensed under the GNU Lesser Public License */
    /* http://www.gnu.org/licenses/lgpl.html */
     
    /* Usage:
        <script language="JavaScript">
            document.write( webcam.get_html(320, 240) );
            webcam.set_api_url( 'test.php' );
            webcam.set_hook( 'onComplete', 'my_callback_function' );
            function my_callback_function(response) {
                alert("Success! PHP returned: " + response);
            }
        </script>
        <a href="javascript:void(webcam.snap())">Take Snapshot</a>
    */
     
    // Everything is under a 'webcam' Namespace
    window.webcam = {
        version: '1.0.9',
         
        // globals
        ie: !!navigator.userAgent.match(/MSIE/),
        protocol: location.protocol.match(/https/i) ? 'https' : 'http',
        callback: null, // user callback for completed uploads
        swf_url: 'webcam.swf', // URI to webcam.swf movie (defaults to cwd)
        shutter_url: 'shutter.mp3', // URI to shutter.mp3 sound
        api_url: '', // URL to upload script
        loaded: false, // true when webcam movie finishes loading
        quality: 90, // JPEG quality (1 - 100)
        shutter_sound: true, // shutter sound effect on/off
        stealth: false, // stealth mode (do not freeze image upon capture)
        hooks: {
            onLoad: null,
            onComplete: null,
            onError: null
        }, // callback hook functions
         
        set_hook: function(name, callback) {
            // set callback hook
            // supported hooks: onLoad, onComplete, onError
            if (typeof(this.hooks[name]) == 'undefined')
                return alert("Hook type not supported: " + name);
             
            this.hooks[name] = callback;
        },
         
        fire_hook: function(name, value) {
            // fire hook callback, passing optional value to it
            if (this.hooks[name]) {
                if (typeof(this.hooks[name]) == 'function') {
                    // callback is function reference, call directly
                    this.hooks[name](value);
                }
                else if (typeof(this.hooks[name]) == 'array') {
                    // callback is PHP-style object instance method
                    this.hooks[name][0][this.hooks[name][1]](value);
                }
                else if (window[this.hooks[name]]) {
                    // callback is global function name
                    window[ this.hooks[name] ](value);
                }
                return true;
            }
            return false; // no hook defined
        },
         
        set_api_url: function(url) {
            // set location of upload API script
            this.api_url = url;
        },
         
        set_swf_url: function(url) {
            // set location of SWF movie (defaults to webcam.swf in cwd)
            this.swf_url = url;
        },
         
        get_html: function(width, height, server_width, server_height) {
            // Return HTML for embedding webcam capture movie
            // Specify pixel width and height (640x480, 320x240, etc.)
            // Server width and height are optional, and default to movie width/height
            if (!server_width) server_width = width;
            if (!server_height) server_height = height;
             
            var html = '';
            var flashvars = 'shutter_enabled=' + (this.shutter_sound ? 1 : 0) + 
                '&shutter_url=' + escape(this.shutter_url) + 
                '&width=' + width + 
                '&height=' + height + 
                '&server_width=' + server_width + 
                '&server_height=' + server_height;
             
            if (this.ie) {
                html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+this.protocol+'://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="webcam_movie" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+this.swf_url+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/></object>';
            }
            else {
                html += '<embed id="webcam_movie" src="'+this.swf_url+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="webcam_movie" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" />';
            }
             
            this.loaded = false;
            return html;
        },
         
        get_movie: function() {
            // get reference to movie object/embed in DOM
            if (!this.loaded) return alert("ERROR: Movie is not loaded yet");
            var movie = document.getElementById('webcam_movie');
            if (!movie) alert("ERROR: Cannot locate movie 'webcam_movie' in DOM");
            return movie;
        },
         
        set_stealth: function(stealth) {
            // set or disable stealth mode
            this.stealth = stealth;
        },
         
        snap: function(url, callback, stealth) {
            // take snapshot and send to server
            // specify fully-qualified URL to server API script
            // and callback function (string or function object)
            if (callback) this.set_hook('onComplete', callback);
            if (url) this.set_api_url(url);
            if (typeof(stealth) != 'undefined') this.set_stealth( stealth );
             
            this.get_movie()._snap( this.api_url, this.quality, this.shutter_sound ? 1 : 0, this.stealth ? 1 : 0 );
        },
         
        freeze: function() {
            // freeze webcam image (capture but do not upload)
            this.get_movie()._snap('', this.quality, this.shutter_sound ? 1 : 0, 0 );
        },
         
        upload: function(url, callback) {
            // upload image to server after taking snapshot
            // specify fully-qualified URL to server API script
            // and callback function (string or function object)
            if (callback) this.set_hook('onComplete', callback);
            if (url) this.set_api_url(url);
             
            this.get_movie()._upload( this.api_url );
        },
         
        reset: function() {
            // reset movie after taking snapshot
            this.get_movie()._reset();
        },
         
        configure: function(panel) {
            // open flash configuration panel -- specify tab name:
            // "camera", "privacy", "default", "localStorage", "microphone", "settingsManager"
            if (!panel) panel = "camera";
            this.get_movie()._configure(panel);
        },
         
        set_quality: function(new_quality) {
            // set the JPEG quality (1 - 100)
            // default is 90
            this.quality = new_quality;
        },
         
        set_shutter_sound: function(enabled, url) {
            // enable or disable the shutter sound effect
            // defaults to enabled
            this.shutter_sound = enabled;
            this.shutter_url = url ? url : 'shutter.mp3';
        },
         
        flash_notify: function(type, msg) {
            // receive notification from flash about event
            switch (type) {
                case 'flashLoadComplete':
                    // movie loaded successfully
                    this.loaded = true;
                    this.fire_hook('onLoad');
                    break;
     
                case 'error':
                    // HTTP POST error most likely
                    if (!this.fire_hook('onError', msg)) {
                        alert("JPEGCam Flash Error: " + msg);
                    }
                    break;
     
                case 'success':
                    // upload complete, execute user callback function
                    // and pass raw API script results to function
                    this.fire_hook('onComplete', msg.toString());
                    break;
     
                default:
                    // catch-all, just in case
                    alert("jpegcam flash_notify: " + type + ": " + msg);
                    break;
            }
        }
    };
    Web.config
    
    
    <?xml version="1.0"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      http://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
        <system.web>
            <compilation debug="true" targetFramework="4.0"/>
            <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
    </configuration>

    -George

    Saturday, April 11, 2020 1:47 PM

All replies

  • User409696431 posted

    "I need help to see if these codes can be edited to make the webcamera read the QR code and redirect someone to whatever information is embedded in the QR. I look forward to getting a solution please."

    That's not what this forum is for.  You should try to modify the code yourself, and come for help if your attempts don't give the result you want.

    Ask yourself some basic questions about your requirement:  If you don't want to push a button to tell the website the code is ready to scan, how will the website know the code is ready to scan?  If the scanned result contains information you can use to identify a new page to redirect to, how will you parse that information from the result?  Show us what you tried.  I assume you know how to redirect to a new page once you know what the page is.

    Saturday, April 11, 2020 2:33 PM
  • User-1994446809 posted
    Thank you kathyW,
    Its a bit difficult for me as I only know how write a cs function code behind a subject. But in this case, it's confusing because the codes are actually not in line with what I knw how to do
    Saturday, April 11, 2020 3:16 PM
  • User475983607 posted

    This is a somewhat complex programming problem that requires image processing.  Find an image processor that detects QR codes.  Then craft code that continuously reads camera images and passes the images to the image processor.   If a QR code is detected then send the information to the web application and provide feedback to the user.

    Are you sure ByteScout does not have the capability to detect a QR code?   Honestly, this is not an ASP.NET support question.  This is more of a research and design question that requires imagine processing knowledge and fundamental JavaScript programming skills.

    Saturday, April 11, 2020 5:58 PM
  • User409696431 posted

    If this is a school project, and you don't have the (considerable) knowledge required to implement your new requirements, is there any reason you can't simply stop with what you have?

    Frankly, if someone wanted me to implement your new requirements, it would be a paid job, not a forum response.

    Saturday, April 11, 2020 7:03 PM
  • User-1994446809 posted

    Thank you, I'll try to see if I can edit the code to achieve the desired result. I appreciate your time. 

    Thank you again.

    Sunday, April 12, 2020 7:09 AM