… Comes Great Responsibility.

In order to make this whole client-side barcode thing work, it is necessary to first develop the engine of rendering. I don’t know whether it was Hulk Hogan or Benjamin Parker who first coined the phrase: “With great power comes great responsibility.”. Regardless, there be great power here, and I’m counting on everyone to be good stewards and not use this power for evil.

With the following couple dozen lines of code and configuration data, you too can make barcodes as realistic as the big boys. All you need to do is wrap the code in ‘<SCRIPT>’ tags as I am about to do and supply the necessary inputs. These are a fairly long string of ‘1’s and ‘0’s (that’s ones and zeroes, boys and girls, not lowercase ‘L’s and capital ‘o’s), a width and a height.

<!DOCTYPE HTML>
<html>
<head>
 <title>Notionovus Barcode Prototype</title>
<script type="text/javascript">

// The MIT License (MIT)

// Copyright (c) 2013, Notionovus, LLC.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// Generic arrays for drawing 5-bit graphics. Building blocks for all barcode symbologies
// Painstakingly derived gobblety-goop, but essentially the two middle sections of image data unique to each graphic
var array5bit_A = new Array ( 'f//AAAAAAAAAAAAAAAAAAAA', 'f//AAAAAAAAAAAAAAAAAAAB', 'f//AAAAAAAAAAAAAAEAAAD/',
 'f//AAAAAAAAAAAAAAEAAAAA', 'f//AAAAAAAAAQAAAP8AAAAA', 'f//AAAAAAAAAQAAAP8AAAAB', 'f//AAAAAAAAAQAAAAAAAAD/',
 'f//AAAAAAAAAQAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAB', 'f//AAABAAAA/wAAAAEAAAD/',
 'f//AAABAAAA/wAAAAEAAAAA', 'f//AAABAAAAAAAAAP8AAAAA', 'f//AAABAAAAAAAAAP8AAAAB', 'f//AAABAAAAAAAAAAAAAAD/',
 'f//AAABAAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAB', 'QD/AAD/AAAAAAAAAAEAAAD/',
 'QD/AAD/AAAAAAAAAAEAAAAA', 'QD/AAD/AAAAAQAAAP8AAAAA', 'QD/AAD/AAAAAQAAAP8AAAAB', 'QD/AAD/AAAAAQAAAAAAAAD/',
 'QD/AAD/AAAAAQAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAB', 'SL/AADeAAAA/gAAAAIAAAD+',
 'QD/AAAAAAAA/wAAAAEAAAAA', 'QD/AAAAAAAAAAAAAP8AAAAA', 'QD/AAAAAAAAAAAAAP8AAAAB', 'QD/AAAAAAAAAAAAAAAAAAD/',
 'QD/AAAAAAAAAAAAAAAAAAAA');
var array5bit_B = new Array ( 'US0CAuSD38g', 'UUYCA7QBErs', 'ajEDAm49ReY', 'UUoCA+juogg', 'bjEDAjQrOn0', 'bkoDA3iPVH4',
 'ajUDAt82atY', 'UU4CA1nljTg', 'cjEDAghkmFU', 'ckoDA0TA9lY', 'izUEAhrxcbg', 'ck4DAxY8F10', 'bjUDAlvFFR8', 'bk4DAxdhexw',
 'ajkDAr7LFAw', 'UVICAyQ+UJI', 'TTECAq7UnEM', 'TUoCA+Jw8kA', 'ZjUDAmZGozo', 'TU4CA7CME0s', 'ajUDAvnk9E4', 'ak4DA7VAmk0',
 'ZjkDAtle3bI', 'TVICAxOyzrM', 'STUCAqHeHtM', 'SU4CA+16cNA', 'h6QEAZKdo54', 'SVICA62zYxM', 'RTkCAqx1lb4', 'RVICA/z3WM0',
 'QT0CAkdoxRU', 'KFYBA46vJCA');

// Painstakingly derived gobblety-goop, but essentially the front, back and mid-matter common to all barcode images...
var stringStart = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/A';
var stringMid = 'AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA';
var stringEnd = 'AAAAASUVORK5CYII=" width="';

//
// Insert Symbology-specific arrays here
//
function genBarcode(inputString,intWidth,intHeight) { // Input is a long string of 1's and 0's, output is the HTML <img> stack

// Pads to the last character to ensure length is divisible by 5
   var intRawmod = inputString.length % 5; // Modulo 5 remainder
   if (intRawmod > 0) for (var i = 0; i < 5 - intRawmod; i++) inputString += "0"; // If not evenly divisible, pad with zeroes
   var arraySeq = new Array (intChunks = inputString.length / 5); // Create array for as many chunks as are now in input string

   for (var i = 0; i < intChunks; i++) arraySeq[i] = parseInt(inputString.substr(i * 5, 5), 2); // Converts string of 1's and 0's to integer array

// Takes integer array and converts to "<img ...>" graphics for display
   var resultString = "";
   for (var i = 0; i < arraySeq.length; i++) {
   	resultString += stringStart + array5bit_A[arraySeq[i]] + stringMid + array5bit_B[arraySeq[i]] + stringEnd + intWidth + '" height="' + intHeight + '">';
   }
   return resultString;
}
</script>
</head>
<body>
 <script>
	document.write(genBarcode('1100011111000011100011001011',10,40));
	document.write(' ta-da! ');
 </script>	
</body>
</html>

As presented, this code is not particularly useful. The barcode symbol does not actually represent any readable value that I am aware of. The input is just a string of ‘1’s and ‘0’s used to illustrate the working software. Here’s what it looks like in a browser:

ta-daIn our next installment, we will walk through the rendering engine and see how it works. In the mean time, please feel free to copy the enclosed HTML / JavaScript into a local HTML file and go nuts with the three parameters. Until next time, thank you for tuning in.