HomeController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace BarcodeReader.Controllers { using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using Bytescout.BarCodeReader; public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(HttpPostedFileBase file) { if (file != null) { string name = file.FileName; string path = Path.Combine(Server.MapPath("/"), Path.GetFileName(name)); file.SaveAs(path); ViewBag.Barcodes = Barcode.FindBarcodes(path); ViewBag.Img = name; } return View(); } [HttpPost] public ActionResult UploadHtml5(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)); bp.Save("c:\\temp\\barcode.jpg",ImageFormat.Jpeg); // new bytescout barcode reader sdk object Reader reader = new Reader(); // get the type to find from user's selection in the combobox reader.BarcodeTypesToFind = Barcode.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 Json(new { d = send.ToString() }); } // end of lock } catch (Exception ex) { // return the exception instead return Json(new { d = ex.Message + "\r\n" + ex.StackTrace }); } } [HttpPost] public ActionResult UploadFlash(string type) { try { String send = ""; System.Drawing.Image originalimg; // read barcode type set 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(() => { return false; }), IntPtr.Zero); Bitmap bp = new Bitmap(originalimg); bp.Save("c:\\temp\\barcode.jpg", ImageFormat.Jpeg); // create bytescout barcode reader object Reader reader = new Reader(); // set barcode type to read reader.BarcodeTypesToFind = Barcode.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 return Content("<d>" + send + "</d>"); } catch (Exception ex) { // write the exception if any return Content("<d>" + ex + "</d>"); } } } }
Barcode.cs
namespace BarcodeReader { using Bytescout.BarCodeReader; public class Barcode { public static FoundBarcode[] FindBarcodes(string fileName) { Reader reader = new Reader(); // Limit search to 1D barcodes only (exclude 2D barcodes to speed up the search). // Change to reader.BarcodeTypesToFind.SetAll() to scan for all supported 1D and 2D barcodes // or select specific type, e.g. reader.BarcodeTypesToFind.PDF417 = True reader.BarcodeTypesToFind.SetAll(); // reader.MediumTrustLevelCompatible = true; // uncomment this line to enable Medium Trust compatible mode (slows down the recognition process as direct image data access is disabled in Medium Trust mode) reader.ReadFromFile(fileName); return reader.FoundBarcodes; } public 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; } } }
index.js
var canvas, context, timer; // (HTML5 based camera only) this portion of code will be used when browser supports navigator.getUserMedia ********* */ window.addEventListener("DOMContentLoaded", function () { canvas = document.getElementById("canvasU"), context = canvas.getContext("2d"), video = document.getElementById("video"), videoObj = { "video": true }, errBack = function (error) { console.log("Video capture error: ", error.code); }; // check if we can use HTML5 based camera (through .getUserMedia() function) if (navigator.getUserMedia) { // Standard browser (Opera) // display HTML5 camera document.getElementById("userMedia").style.display = ''; // adding click event to take photo from webcam document.getElementById("snap").addEventListener("click", function () { context.drawImage(video, 0, 0, 640, 480); }); navigator.getUserMedia(videoObj, function (stream) { video.src = window.URL.createObjectURL(stream); video.play(); }, errBack); } // check if we can use HTML5 based camera (through .getUserMedia() function in Webkit based browser) else if (navigator.webkitGetUserMedia) { // WebKit-prefixed for Google Chrome // display HTML5 camera document.getElementById("userMedia").style.display = ''; // adding click event to take photo from webcam document.getElementById("snap").addEventListener("click", function () { context.drawImage(video, 0, 0, 640, 480); }); navigator.webkitGetUserMedia(videoObj, function (stream) { video.src = window.webkitURL.createObjectURL(stream); video.play(); }, errBack); } // check if we can use HTML5 based camera (through .getUserMedia() function in Firefox based browser) else if (navigator.mozGetUserMedia) { // moz-prefixed for Firefox // display HTML5 camera document.getElementById("userMedia").style.display = ''; // adding click event to take photo from webcam document.getElementById("snap").addEventListener("click", function () { context.drawImage(video, 0, 0, 640, 480); }); navigator.mozGetUserMedia(videoObj, function (stream) { video.mozSrcObject = stream; video.play(); }, errBack); } else // if we can not use any of HTML5 based camera ways then we use Flash based camera { // display Flash camera document.getElementById("flashDiv").style.display = ''; document.getElementById("flashOut").innerHTML = (webcam.get_html(640, 480)); } }, false); // (all type of camera) set the default selection of barcode type var selection = "All barcodes (slow)"; // (all type of camera) gets the selection text of "barcode type to scan" combobox function selectType(type) { selection = type.options[type.selectedIndex].text; } // (HTML5 based camera only) // uploads the image to the server function UploadToCloud() { document.getElementById('report').innerHTML = "scanning the current frame......"; context.drawImage(video, 0, 0, 640, 480); $("#upload").attr('disabled', 'disabled'); $("#upload").attr("value", "Uploading..."); var img = canvas.toDataURL('image/jpeg', 0.9).split(',')[1]; // send AJAX request to the server with image data $.ajax({ url: "/Home/UploadHtml5", type: "POST", data: "{ 'image': '" + img + "' , 'type': '" + selection + "'}", contentType: "application/json; charset=utf-8", dataType: "json", // on success output the result returned by the server side (See HTML5Camera.aspx) success: function (data, status) { $("#upload").removeAttr('disabled'); $("#upload").attr("value", "Upload"); if (data.d.length != 0) { var htmlSelect = document.getElementById('OutListBoxHTML5'); var selectBoxOption = document.createElement("option"); selectBoxOption.text = data.d; selectBoxOption.id = "child"; htmlSelect.insertBefore(selectBoxOption, htmlSelect.childNodes[0]); } }, // on error just show the message that no barcodes were found error: function (data) { document.getElementById('report').innerHTML = "no barcode found, scanning....."; $("#upload").removeAttr('disabled'); $("#upload").attr("value", "Upload"); }, async: false }); timer = setTimeout(UploadToCloud, 3000); // will capture new image to detect barcode after 3000 mili second } // (flash based camera only) stop the capturing function stopCall() { document.getElementById('report').innerHTML = "STOPPED Scanning." clearTimeout(timer); } // (flash based camera only) sets the handler for callback completition to output the result webcam.set_hook('onComplete', 'my_completion_handler'); // (flash based camera only) this function will start flash to capture image and send the image to the server for further processing (for IE) function take_snapshot() { // set api to be called by flash camera webcam.set_api_url('/home/UploadFlash?type=' + selection); webcam.set_quality(100); // enable the shutter sound webcam.set_shutter_sound(true); document.getElementById('upload_results').innerHTML = '<h4>Scanning...</h4>'; // capture image from the webcam webcam.snap(); // set timout to capter new image (interval between captures) timer = setTimeout(take_snapshot, 3000); } // (flash based camera only) this one will work after recieving barcode from server // this function writes the output result back to the front page (from server side) function my_completion_handler(msg) { var str = msg; // encode into html compatible string var result = str.match(/<d>(.*?)<\/d>/g).map(function (val) { return val.replace(/<\/?d>/g, ''); }); // add new result into the listbox var htmlSelect = document.getElementById('OutListBoxFlash'); var selectBoxOption = document.createElement("option"); selectBoxOption.text = result; selectBoxOption.id = "child"; htmlSelect.insertBefore(selectBoxOption, htmlSelect.childNodes[0]); // reset webcam and flash to capture new image. this reset process flickers a little webcam.reset(); } // (flash based camera only) stop the scan and set the message on the page function stopScanning() { document.getElementById('upload_results').innerHTML = "STOPPED Scanning." clearTimeout(timer); }
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"?> <configuration> <configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Optimization"/> <add namespace="System.Web.Routing" /> <add namespace="BarcodeReader" /> </namespaces> </pages> </system.web.webPages.razor> <appSettings> <add key="webpages:Enabled" value="false" /> </appSettings> <system.webServer> <handlers> <remove name="BlockViewHandler"/> <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> </handlers> </system.webServer> <system.web> <compilation> <assemblies> <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </assemblies> </compilation> </system.web> </configuration>
Web.config
<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=301880 --> <configuration> <appSettings> <add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5.2" /> <httpRuntime targetFramework="4.5.2" /> <httpModules> <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" /> </httpModules> </system.web> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" /> <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" /> </dependentAssembly> </assemblyBinding> </runtime> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" /> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" /> </compilers> </system.codedom> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <modules> <remove name="ApplicationInsightsWebTracking" /> <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" /> </modules> </system.webServer> </configuration>