Notionovus has just recently been granted the logo mark you see above and at the top of the page by the U.S. Patent and Trademark Office. The logo above is a 3D stylized version of the registered logo, but keeps in the theme of two arrowheads forming the shape of the capital letter ‘N’. This means that beyond copyright, use of the logo is restricted to Notionovus’ software and weblogs.
I apologize to anyone finding this site neglected. I have been working on a project that I will be discussing at length. I just can’t talk about it right now. I can give you a hint. It has to do with my real passion. If someone is surprised that barcodes isn’t it, well, I’ll quote that old sage Bugs Bunny, “He don’t know me very well, do he?” My goal is to be back up and running by the end of February (2014, for all you people out there that know how software people think) at the latest.
Code 39 takes me way back to sinking my teeth into my first real barcode programming experience. Code 39 is a very simple and straightforward code set consisting of 43 unique representable characters and one start and stop character: the asterisk “*”. If you’ve never done any work with barcodes before, this is a no-brainer selection for an introductory symbology. As such, we can make this lesson a very simple one. I will explain how you can, using the code from the September 19th, 2013 post, generate real, scannable codes in minutes.
The Code 39 Setup
// Symbology-specific arrays var arrayCode39Bin = new Array ( '1010001110111010', '1110100010101110', '1011100010101110', '1110111000101010', // 0, 1, 2, 3 '1010001110101110', '1110100011101010', '1011100011101010', '1010001011101110', // 4, 5, 6, 7 '1110100010111010', '1011100010111010', '1110101000101110', '1011101000101110', // 8, 9, A, B '1110111010001010', '1010111000101110', '1110101110001010', '1011101110001010', // C, D, E, F '1010100011101110', '1110101000111010', '1011101000111010', '1010111000111010', // G, H, I, J '1110101010001110', '1011101010001110', '1110111010100010', '1010111010001110', // K, L, M, N '1110101110100010', '1011101110100010', '1010101110001110', '1110101011100010', // O, P, Q, R '1011101011100010', '1010111011100010', '1110001010101110', '1000111010101110', // S, T, U, V '1110001110101010', '1000101110101110', '1110001011101010', '1000111011101010', // W, X, Y, Z '1000101011101110', '1110001010111010', '1000111010111010', '1000100010001010', // -, ., (space), $ '1000100010100010', '1000101000100010', '1010001000100010', '1000101110111010'); // /, +, %, * var strCode39 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*";
Take these lines of code and add them to the bottom of the Setup portion of the file given out in the September 19th article.
The first array (arrayCode39Bin) is the set of raw sequences of ones and zeroes that will direct our rendering engine to generate the proper sequence of bars, lines and spaces corresponding to each of the 44 characters that the Code 39 symbology can represent. The second array (strCode39) is really that string of 44 characters in the numerical order which ties them to the previous array.
Replace the <body> element in the sample code from the previous article with the element provided in this article.
Here is the essence of what gets output to the browser document:
This generates a scannable barcode in the browser. If you print this page and scan it, the scanner will dump 123TEST890 as output. The code string has an asterisk embedded before and after the data, but those are required and necessary for scanning a Code 39 code. The asterisk (“*”) is not a valid data character.
We will run some more complex symbologies in future installments, including Code 128, Interleaved 2 of 5 and ultimately QR Code before we finally reach the application area and we get to shipping label and shop floor routing software. Until next time, thanks for tuning in.
I don’t particularly care for line-by-line code reviews. I don’t think they convey much meaning, even to people who think like computers. But you have to understand the inner workings of the software published earlier before I turn you loose on society. Thankfully, there are only about ten lines of code in the software and three major areas, so covering them should be a breeze for both you and me. So, copy the source code from the last article into your favorite text editor and follow along. Trust me, this won’t hurt a bit.
The three major sections are the setup data, the chunkifier and the rendering engine.
Sounds like a subtitle for a good slasher movie, eh? The chunkifier is the four lines of code starting with the initialization of the intRawmod variable and ending with the for loop that populates the arraySeq array. In short, what the chunkifier does is break down a long string of ones and zeroes into a sequence of 5-bit integers.
The Rendering Engine
The rendering engine takes the sequence of 5-bit integers created by the chunkifier and builds the <img> elements necessary to render the array. This is a very simple loop and uses the integers found in the sequence to look up the unique text found in array5bit_A and array5bit_B and patch it together with the start, middle and end string constants so we have an <img> element that parses and scales to display a series of bars and spaces.
What you would see, if you used the rendering engine to output to a text file from the demonstration at the end of the last article is:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/AQD/AAAAAAAA/wAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAASTUCAqHeHtMAAAAASUVORK5CYII=" width="10" height="40"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/AQD/AAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAKFYBA46vJCAAAAAASUVORK5CYII=" width="10" height="40"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/Af//AAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAUUYCA7QBErsAAAAASUVORK5CYII=" width="10" height="40"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/AQD/AAAAAAAA/wAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAASTUCAqHeHtMAAAAASUVORK5CYII=" width="10" height="40"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/AQD/AAAAAAAA/wAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAASU4CA+16cNAAAAAASUVORK5CYII=" width="10" height="40"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/Af//AAABAAAAAAAAAP8AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAbjUDAlvFFR8AAAAASUVORK5CYII=" width="10" height="40">
There are no line feeds or carriage returns embedded in the output text for a very good reason covered earlier. The text consists only of HTML entities. So, it takes six HTML images to render that very simple pseudo-barcode we saw last time (near the anti-climactic “ta-da!”). Next time we are going to demonstrate doing something non-trivial with the rendering engine by hooking it up to some code that actually generates valid barcodes. Until next time, thanks for tuning in.
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.
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:
So, I stuck with my original brilliant idea and positioned a bunch of client-side PNG images next to one another. Because the original idea worked from thinking that barcodes are really depictions of disproportionately scaled Morse-code-like ‘1’s and ‘0’s, I needed an approach that would take any generic bit stream and render it. There are 256 unique bit values in a byte, but because 107 images were somewhat unwieldy in the “brute force” method, I decided to slim that down to something more manageable. I discarded 7-bits per image (128 combinations) and 6-bits per image (64 combinations) as options before I decided to try 5-bits per image. I suppose that I could have gone down to one bit per image, but I was concerned about performance. Perhaps I’ll save that experiment for later.
A refresher is in order if you are unfamiliar with the exact technique I used to get the bitmapped graphic into base-64 PNG images. I’m not going to get too deep into the details of Barcode Tools and Techniques in this or future postings, so a detailed discussion can be found Under Barcodes->HTML->Code 128 Barcode on this website. I used the same technique that I used for the Code 128 “brute force” method for each possible bitmap representing 0-31, or ‘00000’ to ‘11111’ in binary.
Unfortunately, the graphical depictions, once converted to PNG, then base-64 were being optimized in a number of cases, but not all. Therefore, I ended up with an unruly mess of base-64 text that I wanted to break down to save some bytes. I decided to try doubling the size of the bitmap so that each bit was represented by a 2×2 pixel map of all black or all white. This yielded much better results as depicted here.
There were some considerations. Since I was rendering barcodes 5-bits at a time, I had to chunkify a string of ‘1’s and ‘0’s of undetermined length into 5 bits. Since not all barcode bit streams are divisible by 5, I had to pad the last remaining bits with ‘0’s to get all the rendering to come out even. Since the ‘0’s just add a maximum of 4 bits of white space to the right hand side of the barcode, and since a minimum quiet zone must be maintained anyway, this has not been an issue. The software generally adds ‘0’s to the front and back of every bit stream regardless.
When we last left the barcode software we had a set of images that represented every character in the Code 128 symbology. There was a Microsoft ExcelWebApp (really a downloadable spreadsheet) that you could use to type in a string to generate your own barcodes. There was also a very in-depth discussion about how you can roll your own barcodes using this same technique.
If you have a little HTML experience, this set of images is all that you need to put a barcode on a website or embed one into an e-mail. The drawback of this method is that it is a little cumbersome and not very highly interactive. If you want several dozen barcodes, the “brute force” technique, as I call it, is not very efficient.
The 2D symbologies had me stumped for a little while because of a much more elaborate error-correction scheme utilizing Reed-Solomon codes. I will have more on that later, but suffice it to say 2D barcodes rely on a buffer of error-correction bytes. These bytes not only inform the scanner if a barcode has been damaged, but help the barcode reader piece together the correct data in the barcode so it doesn’t necessarily have to report an unreadable symbol.
- The symbols themselves had to go.
- Separate the symbology-specific logic from the rendering.
The Symbol Agnostic “Metafont”
Separated For Their Own Good
Before I divulge the complete package, I want to walk through the creation of the new software. I also want to have an understanding, up front, that this software has been contrived by yours truly. Therefore, in its published form, it will contain the following text:
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.
You are approved to use the software as you see fit, but if you use the software in its entirety in a republished work, it is expected that credit will be given and the copyright notice will not be removed.
In the next installment of this series, we will dive into the mechanics of the barcode generation code. Until next time, thank you for tuning in.
I am studying the following books: The Lean Startup by Eric Ries, Running Lean by Ash Maurya and Business Model Generation by Alexander Osterwalder and Yves Pigneur. While I tend to think of myself as traditional, I am always open to studying new techniques, especially if they help me to eliminate waste.
A seemingly recurring theme with these books is the non-traditional approach to the business plan. I have a traditional business plan. I started on it one year ago with some help from SCORE Peoria. I show it to people occasionally, to give them an idea that this Notionovus thing isn’t just a whim and that I’ve put some thought into how I would approach investors.
The problem is, I am not ready to approach investors. I am not confident in the applicability of my technical skills to today’s IT challenges. I want to give my business some time for study and ideation. I have to draw up a vision for how we will do business. In short, “Pay no attention to the man behind the curtain.”.
The problem with a traditional business plan is its purpose. It is intended to show investors and bankers that you are ready for some form of financing to take your business to “the next level”. Without that exercise, a business plan seems a poor fit as I am using it. The business plan is not dynamic. Changing one assumption forces you to revisit many other assumptions. You find yourself needing to edit several sections at once, and the sections aren’t linked together like a spreadsheet. Each part of a business plan requires deep thought.
It’s not that I don’t think business plans are valuable. I just think that if all you are going to do is show your business plan to others as a means of discussing your business ideas, there are more efficient ways to layout your talking points. I am referring to the Lean Canvas. My guideline for developing Notionovus’ Lean Canvas was the Business Model Generation book. This book lays the instruction for building a Lean Canvas out for any venture in an easy to understand format. Plenty of examples, lots of pictures, my kind of book.
In a future blog entry, I’ll navigate the Notionovus Lean Canvas with you and explain the abbreviated notions. I think the Lean Canvas is easier to work with and helps me speak to others about my business. I highly recommend the books mentioned at the beginning of this article if you are working on your own startup.
Until next time, thank you for tuning in.
Hello. This is Brian Anderson again. I gave a brief introduction to myself in July of 2012. If you are curious, the best way to get to know more about me is through my LinkedIn page.
I have not been updating this site as frequently as I would have liked. This is partially because I have had too much to write about and partially because I have not been confident that this weblog is the ideal venue. I recently took a fantastic class on Content Management Systems taught by Mark DuBois for Working Connections and it really opened my eyes to some of the interesting things I could do with this website, so I am newly committing myself to keeping this site more up-to-date.
The site will be restructured as follows:
I have found some quirks with the browsers and some other technical challenges I am working on before I can get this code “production ready”, but in the coming weeks I will be posting my progress. Until next time, thank you for tuning in.