updated on 5 February 2014 (to include support for Internet Explorer 9+)
It is easy with HTML5, Javascript, and the latest version of BarCode Reader SDK!
Screenshot of the Google Chrome browser (Internet Explorer, Firefox, Safari are also supported!) running ASP.NET code reading Code 128 barcodes from online web camera:
Visual Studio 2008/2010 or higher is required for this sample to run!
Select barcode type to scan if need to scan a particular barcode type (by default scans for all known types).
Here is the code:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1. Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head id=”Head1″ runat=”server”>
<title></title>
<script src=”http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js” type=”text/javascript”></script>
<script type=”text/javascript” src=”webcam.js”></script>
<!– this javascript plugin uses the webcam.swf file to capture image and send the image to server for further processing –>
<script type=”text/javascript”>
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 = 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: “HTML5Camera.aspx/Upload”,
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 completion 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(‘FlashCamera.aspx?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 timeout to capture a new image (interval between captures)
timer = setTimeout(take_snapshot, 3000);
}
// (flash-based camera only) this one will work after receiving 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 a 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);
}
</script>
<style>
span
{
font-size:20px;
}
</style>
</head>
<body>
<form id=”form1″ runat=”server”>
<!– HTML5 camera based capturing section –>
<!– this div block will be shown when browser supports get user media–>
<div id=”userMedia” style=”display:none; height: 575px; width: 1182px”>
<table>
<tr align=”left” valign=”top”>
<td valign=”top” colspan=”2″>
<h3 style=” color:Green; “>(HTML5 based camera) This works in Chrome, Firefox, Safari and other modern browsers with HTML5 support. If the HTML5 camera is not enabled then Flash-based camera should appear instead. To enable webcam access answer ALLOW when asked if you want to give access to webcam </h3>
</td>
</tr>
<tr align=”left” valign=”top”>
<td valign=”top”>
<h2 id=”choiceU”> <b>Barcode Type To Scan (to start barcode scan – click START below)</b></h2>
<br />
<select id=”comboBoxBarCodeTypeHTML5″ onchange=”selectType(this)”>
<option value=”1″>All Barcodes (slow)</option>
<option value=”2″>All Linear Barcodes (Code39, Code 128 etc)</option>
<option value=”3″>All 2D Barcodes (QR Code, Aztec, Datamtrix, PDF417 and others)</option>
<option value=”4″>Code 39c</option>
<option value=”5″>Code 128</option>
<option value=”6″>EAN 13</option>
<option value=”7″>UPCA</option>
<option value=”8″>GS1-128</option>
<option value=”9″>GS1DataBarExpanded</option>
<option value=”10″>GS1DataBarExpandedStacked </option>
<option value=”11″>GS1DataBarLimited</option>
<option value=”12″>GS1DataBarOmnidirectional</option>
<option value=”13″>GS1DataBarStacked</option>
<option value=”14″>I2of5</option>
<option value=”15″>Patch Code</option>
<option value=”16″>PDF 417</option>
<option value=”17″>QR Code</option>
<option value=”18″>Datamatrix</option>
<option value=”19″>Aztec</option>
<option value=”20″>MaxiCode</option>
</select>
<br />
<span style=” font-size:20px; “>Output barcode values read appears below: </span>
<br />
<!– decoding results appear in this listbox –>
<select style=”width:500px; height:100px;” size=”8″ id=”OutListBoxHTML5″>
</select>
<br />
<input id=”snap” style=”color:black; font-weight:bold; font-size:x-large;” type=”button” onclick=”UploadToCloud();” value=”START READING BARCODES…” />
<input id=”pause” style=”color:black;” type=”button” onclick=”stopCall();” value=”STOP” /> <h4 id=”report” >
</td>
<td valign=”top”>
<span>Webcam preview shows below:</span>
<video id=”video” width=”640″ height=”480″></video>
<!– canvas with the output –>
<canvas id=”canvasU” width=”640″ height=”480″ style=”display:none” ></canvas>
</td>
</tr>
</table>
</div>
<!– Flash (SWF) camera-based capturing section –>
<!– this div block will be shown when the browser does not support user media so the only way is to capture with flash (swf) camera –>
<div id=”flashDiv” style=” display:none; “>
<table>
<tr align=”left” valign=”top”>
<td colspan=”2″><h3 style=” color:Green; ” >(FLASH based camera) This works in Internet Explorer 9+, Chrome, Firefox and other browsers with flash support. To enable web-cam access answer ALLOW when asked if you want to give access to webcam </h3></td>
</tr>
<tr align=”left” valign=”top”>
<td valign=”top”>
<h4 id=”choice”> <b>Barcode Type To Scan (to start barcode scan – click START below)</b></h4>
<br />
<select id=”comboBoxBarCodeTypeFlash” onchange=”selectType(this)”>
<option value=”1″>All Barcodes (slow)</option>
<option value=”2″>All Linear Barcodes (Code39, Code 128, EAN 13, UPCA, UPCE etc)</option>
<option value=”3″>All 2D Barcodes (QR Code, Aztec, Datamtrix, PDF417 and others)</option>
<option value=”4″>Code 39</option>
<option value=”5″>Code 128</option>
<option value=”6″>EAN 13</option>
<option value=”7″>UPCA</option>
<option value=”8″>GS1-128</option>
<option value=”9″>GS1DataBarExpanded</option>
<option value=”10″>GS1DataBarExpandedStacked </option>
<option value=”11″>GS1DataBarLimited</option>
<option value=”12″>GS1DataBarOmnidirectional</option>
<option value=”13″>GS1DataBarStacked</option>
<option value=”14″>I2of5</option>
<option value=”15″>Patch Code</option>
<option value=”16″>PDF 417</option>
<option value=”17″>QR Code</option>
<option value=”18″>Datamatrix</option>
<option value=”19″>Aztec</option>
<option value=”20″>MaxiCode</option>
</select>
<br />
<span style=” font-size:20px; “>Output barcode values read appears below: </span>
<br />
<!– decoding results appear in this listbox –>
<select style=”width:500px; height:100px;” size=”8″ id=”OutListBoxFlash”> </select>
<br />
<input type=”button” style=”color:black; font-weight:bold; font-size:x-large;” value=”START READING BARCODES..” onclick=”take_snapshot()”/>
<br />
<input type=”button” style=”color:black; font-weight:bold; font-size:x-large;” value=”STOP” onclick=”stopScanning()”/>
<br />
</div>
<div id=”upload_results” style=”background-color:#eee;”></div>
</td>
<td>
<div id=”flashOut”> </div>
</td>
</tr>
</table>
</form>
</body>
</html>
(used for Internet Explorer and other flash enabled browsers):
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 { // default scan type set to all barcode types private static SymbologyFilter m_barcodeTypeToScan = SymbologyFilter.FindAll; 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.TypeToFind = 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 SymbologyFilter GetBarcodeTypeToFindFromCombobox(string barType) { string selectedItemText = barType.Trim().ToUpper(); if (selectedItemText.IndexOf("ALL BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll; else if (selectedItemText.IndexOf("ALL LINEAR BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll1D; else if (selectedItemText.IndexOf("ALL 2D BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll2D; else if (selectedItemText.IndexOf("AZTEC") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAztec; else if (selectedItemText.IndexOf("CODABAR") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCodabar; else if (selectedItemText.IndexOf("CODE 39") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCode39; else if (selectedItemText.IndexOf("CODE 128") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCode128; else if (selectedItemText.IndexOf("DATAMATRIX") > -1) m_barcodeTypeToScan = SymbologyFilter.FindDataMatrix; else if (selectedItemText.IndexOf("EAN 13") > -1) m_barcodeTypeToScan = SymbologyFilter.FindEAN13; else if (selectedItemText.IndexOf("GS1-128") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1; else if (selectedItemText.IndexOf("GS1DATABAREXPANDED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarExpanded; else if (selectedItemText.IndexOf("GS1DATABAREXPANDEDSTACKED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarExpandedStacked; else if (selectedItemText.IndexOf("GS1DATABARLIMITED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarLimited; else if (selectedItemText.IndexOf("GS1DATABAROMNIDIRECTIONAL") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarOmnidirectional; else if (selectedItemText.IndexOf("GS1DATABARSTACKED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarStacked; else if (selectedItemText.IndexOf("I2OF5") > -1) m_barcodeTypeToScan = SymbologyFilter.FindInterleaved2of5; else if (selectedItemText.IndexOf("PATCH") > -1) m_barcodeTypeToScan = SymbologyFilter.FindPatchCode; else if (selectedItemText.IndexOf("PDF 417") > -1) m_barcodeTypeToScan = SymbologyFilter.FindPDF417; else if (selectedItemText.IndexOf("QR CODE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindQRCode; else if (selectedItemText.IndexOf("UPCA") > -1) m_barcodeTypeToScan = SymbologyFilter.FindUPCA; else if (selectedItemText.IndexOf("UPCE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindUPCE; else if (selectedItemText.IndexOf("MAXICODE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindMaxiCode; return m_barcodeTypeToScan; } }
(used for HTML5 enabled browsers)
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;FFla using System.Drawing; using System.Drawing.Imaging; using System.Threading;
public partial class Camera : System.Web.UI.Page { private static SymbologyFilter m_barcodeTypeToScan = SymbologyFilter.FindAll; 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 { String send = ""; // 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.TypeToFind = 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 = send + "rn"+ (String.Format("{0} : {1}", barcode.Type, barcode.Value)); } } // return the output string return send; } // end of lock } catch (Exception ex) { // return the exception instead return (ex.Message + "rn" + ex.StackTrace); }
} /// <summary> /// Get symbology filter for the SDK from the combobox selection text /// </summary> /// <param name="barType"></param> /// <returns></returns> private static SymbologyFilter GetBarcodeTypeToFindFromCombobox(string barType) { string selectedItemText = barType.Trim().ToUpper(); if (selectedItemText.IndexOf("ALL BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll; else if (selectedItemText.IndexOf("ALL LINEAR BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll1D; else if (selectedItemText.IndexOf("ALL 2D BARCODES") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAll2D; else if (selectedItemText.IndexOf("AZTEC") > -1) m_barcodeTypeToScan = SymbologyFilter.FindAztec; else if (selectedItemText.IndexOf("CODABAR") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCodabar; else if (selectedItemText.IndexOf("CODE 39") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCode39; else if (selectedItemText.IndexOf("CODE 128") > -1) m_barcodeTypeToScan = SymbologyFilter.FindCode128; else if (selectedItemText.IndexOf("DATAMATRIX") > -1) m_barcodeTypeToScan = SymbologyFilter.FindDataMatrix; else if (selectedItemText.IndexOf("EAN 13") > -1) m_barcodeTypeToScan = SymbologyFilter.FindEAN13; else if (selectedItemText.IndexOf("GS1-128") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1; else if (selectedItemText.IndexOf("GS1DATABAREXPANDED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarExpanded; else if (selectedItemText.IndexOf("GS1DATABAREXPANDEDSTACKED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarExpandedStacked; else if (selectedItemText.IndexOf("GS1DATABARLIMITED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarLimited; else if (selectedItemText.IndexOf("GS1DATABAROMNIDIRECTIONAL") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarOmnidirectional; else if (selectedItemText.IndexOf("GS1DATABARSTACKED") > -1) m_barcodeTypeToScan = SymbologyFilter.FindGS1DataBarStacked; else if (selectedItemText.IndexOf("I2OF5") > -1) m_barcodeTypeToScan = SymbologyFilter.FindInterleaved2of5; else if (selectedItemText.IndexOf("PATCH") > -1) m_barcodeTypeToScan = SymbologyFilter.FindPatchCode; else if (selectedItemText.IndexOf("PDF 417") > -1) m_barcodeTypeToScan = SymbologyFilter.FindPDF417; else if (selectedItemText.IndexOf("QR CODE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindQRCode; else if (selectedItemText.IndexOf("UPCA") > -1) m_barcodeTypeToScan = SymbologyFilter.FindUPCA; else if (selectedItemText.IndexOf("UPCE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindUPCE; else if (selectedItemText.IndexOf("MAXICODE") > -1) m_barcodeTypeToScan = SymbologyFilter.FindMaxiCode; return m_barcodeTypeToScan; } }