|
Introduction
This article and its code provide a way for developers to put barcodes into their applications. It allows for the generation of barcode images without the use of "barcode fonts". This need arose out of the necessity for one of my own projects to use barcodes and the lack of free libraries on the Web to do the job.
To give an idea of what happens in this library: it first turns the data into a series of 1s and 0s representing equal-width bars and spaces. This string of binary information is then sent to a drawing function that converts it to an image representing the desired barcode. This approach allows for one common drawing method to be used on all symbologies.
Supported Encoding Types
| Codabar |
Code11 |
Code 39(Extended / Full ASCII) |
| Code 128 |
EAN-8 |
EAN-13 |
| Interleaved 2 of 5 |
ISBN |
JAN-13 |
| MSI |
PostNet |
Standard 2 of 5 |
| UPC-A |
UPC-E |
UPC Supplemental 2 |
| UPC Supplemental 5 |
|
|
** Keep in mind some symbologies go by more than one name so make sure the one you are using isn't listed above by a different name before contacting me to add it. If it isn't listed above and you would like me to look at adding it to this library, please post a comment below and I will take a look at it as soon as possible. (Bugs are always a priority, so please send me bug reports.)
Using the Code
The library contains one class called BarcodeLib. There are three constructors:
Barcode();
Barcode(string);
Barcode (string, BarcodeLib.TYPE);
If you decide to create an instance with parameters, the parameters are as follows:
The string is the data to be encoded into the barcode and the BarcodeLib.TYPE is the symbology to encode the data with. If you do not choose to specify the data and type at the time the instance is created, you may specify them through the appropriate property later on (but before you encode).
BarCodeLib.Barcode b = new BarCodeLib.Barcode("038000356216",
BarCodeLib.TYPE.UPCA);
To get the image representing the data generated, you must then call one of the many Encode functions.
public Image Encode(TYPE iType, string StringToEncode, double percent)
public Image Encode(TYPE iType, double percent)
public Image Encode(TYPE iType, string StringToEncode, int Width, int Height)
public Image Encode(TYPE iType, int Width, int Height)
public Image Encode(TYPE iType, string StringToEncode, Color DrawColor,
Color BackColor, double percent)
public Image Encode(TYPE iType, string StringToEncode, Color DrawColor,
Color BackColor, int Width, int Height)
public Image Encode(TYPE iType, string StringToEncode, Color DrawColor,
Color BackColor)
public Image Encode(TYPE iType, Color DrawColor, Color BackColor)
public Image Encode(TYPE iType, string StringToEncode)
public Image Encode(TYPE iType)
public Image Encode()
The resulting Image contains the barcode in image format. More functionality has been added, so you can save the Image once it is encoded.
public void SaveImage(string Filename, SaveTypes FileType)
This function can be used by specifying the full path (filename included) of the location you would like to save the image to as a string. The second parameter is an enumerator (BarcodeLib.SaveTypes) that represents the supported types (JPG, BMP, PNG, GIF, TIFF) of files you can save. Functionality has been added so that you can now call:
public Image Generate_Labels(Image img)
This is used to put the data encoded at the bottom of the image. If you do not call this function, it will just generate the barcode without the data at the bottom.
Points of Interest
Writing this library offered me the chance to become intimately familiar with how barcode symbologies work and how the symbologies differ from one another.
History
-
October 10th, 2007 - Initial release (bugs most certainly exist and a couple of symbologies need to be modified/implemented)
-
October 16th, 2007 - Updated Encode_Code39() to fix a bug that didn't include inter-character spaces. Also updated the function Generate_Image(Color, Color) and replaced the section using SetPixel with the following:
using (Graphics g = Graphics.FromImage(b))
{
g.DrawLine(new Pen(c), x, 0, x, b.Height);
g.DrawLine(new Pen(c), x + 1, 0, x + 1, b.Height);
}
-
October 17th, 2007 - Changed the Generate_Image(Color, Color) function again to be a little more efficient. Instead of drawing two lines, it just uses a 2px-wide pen now. Thanks for the comments; they continue to make this library better.
using (Graphics g = Graphics.FromImage(b))
{
g.DrawLine(new Pen(c, (float)2), new Point(x, 0),
new Point(x, b.Height));
}
Also, functionality was added so that if you call BarcodeLib.Generate_Labels(Image), it will add the label showing the data encoded at the bottom of the barcode.
Fixed a bug in the Test application where, if you encoded with PostNet as the type, it would automatically try to put the label at the bottom and labels aren't available on PostNet images. This caused it to throw an error that a Try{}Catch{} can handle for now.
Took c0ax_lx's advice and moved...
using (Graphics g = Graphics.FromImage(b))
... outside the while loop to improve resource usage.
-
October 26th, 2007 - Article edited and moved to the main CodeProject article base.
-
November 1st, 2007 - Complete restructuring of the library to abstract portions of it. Should be much cleaner to look at. An interface was added to force any updates to adhere to the structure. There were some bugs that were fixed in this release. Some of the encoding types on the menu were encoding with a different type than they said. Changed CheckNumericOnly() to be 1 line of code instead of a massive O^2 complicated take. (Thanks, Pete)
-
December 9th, 2007 - Bug fixed in UPC-E encoding that would cause an index out of range exception to be thrown. (Thanks Luca Z.)
int pos = 0;
This library is getting better with the help of people like Luca and Pete. Keep up the good work friends.
-
April 16th, 2008 - Code 128 support is here. It is still very much in the beta phase (the FNC* chars are still not encoding right... I have to figure that out) but ... it's at least here for your trial and for your comments. Also, there were a few country codes left out of the EAN-13 assigning country lookup. I added what I could find that I left out. If you find any more, just let me know. Thanks again for your support and help.
I also had to change the CheckNumericOnly() back to a more complex task because some data being encoded was longer than what Int64.TryParse(string, out) could handle ... so back to a more complex but still a faster task than comparing each char. Now I break the string into pieces and test each piece.
-
May 3rd, 2008 - Code 128 had some bug fixes added. One was present in InsertStartandCodeCharacters(). The other was when trying to encode an apostrophe, it needed an escape character when selecting the data for it from the dataset. This should fix all the bugs for now ... if you find any more, let me know so I can try to track them down. Thanks again for your support.
-
May 27th, 2008 - PostNet now supports 5, 6, 9, 11 digit data. Also, a bug with the checkdigit for PostNet is fixed. Code 128 now supports specifying and locking the encoding to a specific type. (Code A, B, C). Code 39 Extended (Full ASCII) is now supported.
-
May 29th, 2008 - Bug fixed (thanks Koru.nl) in Bitmap Generate_Image(Color DrawColor, Color BackColor) that caused the drawing to be off by one horizontal pixel. This caused the drawing to cut 1 pixel width off the first bar that was drawn if it was drawn up against the edge of the image. The drawing function also changed a bit to eliminate the variable int x; from the function. All positions are now calculated off the variable int pos; which cuts out one unnecessary and confusing variable.
-
July 30th, 2008 - Bug fixed (thanks Kazna4ey and WolfgangRoth) in init_Code128() that caused .Select(string filterExpression) to return the wrong rows due to case insensitivity. So the following was added:
this.C128_Code.CaseSensitive = true;
Another function byte[] GetImageData(SaveTypes savetype) was added so that users may request the bytes of the image easily. (Useful if using Crystal Reports, etc.)
-
August 26th, 2008 - Bug fixed (thanks JackyWu2005) in Code128.cs that was preventing the proper start characters from being inserted. This only happened when switching back to A from any other encoding type.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 263 (Total in Forum: 263) (Refresh) | FirstPrevNext |
|
|
 |
|
|
Hi,
first let me say - it ist a very good program, but found a bug, by trying to open the JPG File with Photoshop - program exports allways as png format, which can be seen by opening the file with an editor.
It is no Problem for Windows to open png Format, but it could be Problem for Customer, because the JPG File isn´t a JPG File.
Sincerly Thorsten
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hi, Your article is the best that I have found. I added BarWeight to switch from 2 to 1 bar with to reduce size of big bar codes, I think the quality will be better then to use ResizeImage function.
int pos = 0; using (Graphics g = Graphics.FromImage(b)) { g.FillRectangle(BrushesBack, 0, 0, b.Width, b.Height); while ((pos * BarWeight + QuietWidth) < b.Width) { if (pos < Encoded_Value.Length) { if (Encoded_Value[pos] == '1') c = DrawColor; if (Encoded_Value[pos] == '0') { pos++; continue; //c = BackColor; } } else break;
g.DrawLine(new Pen(c, (float)BarWeight), new Point(pos * BarWeight + QuietWidth, 0), new Point(pos * BarWeight + QuietWidth, b.Height));
pos++; }//while
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Ill take a look at this feature and see if I can find a way to include it in the library.
Thanks
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Does anyone have a good example of how to use the SaveAdd Method of the generate labels class? I have been trying, but I'm not sure what parameters I need to send in to get them to save. If I can see a simple example I can probably take it from there.
Ken
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I dont have a "SaveAdd" method in any class? Are you talking about the SaveImage function? Let me know because I am baffled as to which function you are talking about.
Thanks for the interest and let me know if I can help.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, it's a bar code to encode a Global Trade Item Number, to make it's very simple because work like Interleaved 2/5
http://en.wikipedia.org/wiki/ITF-14[^]
the last char is a checksum with the same algorithm of ean13...
To make a ITF-14 is a very simple, get the 13 chars make the 14 checksum char and encode all with the Interleaved 2/5 method...
This it's a suggest to implement a new barcode based on existing encoding.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Ill take a look at it sometime ... maybe this weekend when I am in Dallas ... Ill carry a laptop with me and see if I can get this knocked out in some spare time.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hi, the difference between the EAN128 and CODE128 is the AI (Application Identifiers)
Before each AI we need insert a FNC1 Character (102 Character from Code128A)
The Structure is This for Example
START (Like Code128) + FNC1 + AI + DATA + CHECK + STOP
For the AI there is a special AI like
310y Product Net Weight in Kg 6 Digits 311y Product Length/1st Dimension (Meters) 6 Digits
or
23x Lot Number 1-19 Alphanumeric
Where Y is the number of decimal in the data Where X is can the containt the lenghe of the data
This kind of barcode is useful in italy in the food industry for the tracking.
modified on Tuesday, August 26, 2008 3:56 AM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
interesting ... maybe it wouldnt be too hard to implement ... Ill have to take a look at it sometime. My home computer is messed up so I am in the process of building another one. It may be a little while before I get it back up and running and get the time to implement it but stay tuned.
Thanks again for all of your interest as it keeps me motivated.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
Thanks again for a nice library. I'm experiencing some problems when using the Code128 implementation though.
When encoding string '08v.57090' using 'Code128-B' and scanning the generated barcode, I get '(v.Y)0' as result. Debugging your code and looking at the resulting FormattedData, I see digitpairs '08', '57' and '09' at positions 2, 5 and 6. These digitpairs can be encoded using 'Code128-C', but are not part of codeset B. I end up with this strange scanresult, because encoding is partly done using codeset C without actually doing a switch to that codeset. Because I explicitly asked for 'Code128-B' switching is not allowed anyway.
Using the same string but trying to encode using 'Code128-A' and 'Code128-C', the string is translated without any problem. As codeset A doesn't contain lowercase letters and codeset C doesn't contain non-digit characters, the encoding of '08v.57090' can't be done using either codeset A or C. An exception should be raised instead.
Encoding the mentioned string using Code128 with automatic codeset switching is done properly, although I would suggest to give preference to using codeset B over codeset A and to stay with a once choosen codeset unless proper encoding is not possible. In your implementation a switch from codeset B to A is done to encode the '.' from '08v.57090', but there is no actual need to switch because a '.' can be encoded with codeset B as well.
For my personal needs I have changed your code to overcome the problems mentioned above. I'm more than happy to provide you with my version of Code128.cs, although I must say I have changed quite a bit. Just let me know, if you are interested.
Kind regards,
Jan.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I have a new version of the library to be posted soon. It fixed a bug one of the other members found. I think it may fix this problem. Keep an eye out for a new version in the coming days. I am going on vacation Friday of this week so I will try to post it before then.
Thanks for the insight and help ... I will try to test that before I post the new version but I want to get atleast the other bug fixed before I leave for vacation. With the other bug I dont see how everyone isnt posting the issue.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Please, don't feel offended by me putting forward those issues. I think you have done a tremendous job of bringing all these different barcodes together in one neat package. I just wanted to be helpful to improve it even further.
Hope, you have an enjoyable holiday,
Jan.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
When I try to encode the string "11UC1884" using "Code 128". It gave the following error:
AN ERROR OCCURRED PRINGTING FILE - EC 128-3: COULD NOT INSERT START AND CODE CHARACTERS, MESSAGE: INDEX WAS OUTSIDE THE BOUNDS OF THE ARRAY
Is there any method to fix this bug?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I used the following method to let the application run. But I am not sure whether it is a good way. Is there any good method to fix this bug?
The method I am using to fix this bug:
In Code128.cs: In InsertStartandCodeCharacters(), find the following code:
CurrentCodeString = CurrentCodeSet[col].ToString().Split(new char[] { '_' })[1];
Replace it with the following code:
try { CurrentCodeString = CurrentCodeSet[col].ToString().Split(new char[] { '_' })[1]; } catch (Exception e) { //If error occuried, it might caused by that there are two rows in the CurrentCodeSet. CurrentCodeSet = tempStartChars[1]; CurrentCodeString = CurrentCodeSet[col].ToString().Split(new char[] { '_' })[1]; }
It would be appreciated if any one can tell me better way to fix this bug. Thanks in advanced.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I found the problem and will post it in the next release. Thanks for your help finding the problem. It happened only when switching back to CODE_A in C128.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thank for your excellent job. How can i use it to generate IMEI (International Mobile Equipment Identity)code?
Thanks, Try
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Never heard of IMEI code ... can you give me the specs or point me to some information on how to generate those barcodes? Are they the same as another one of the supported barcodes? If so I might be able to generate them as well.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
IMEI is used to identified mobile phone. Here is its spec http://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity
Thanks, Try
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
It looks as if its a code but not a barcode ... the barcode representation of this is more than likely 2D Datamatrix ... or it is on the newer ones.
As of right now there is a plan to implement 2D barcodes but no definate timeline for putting that in there. (I guess when winter comes and R/C Cars aren't the prominent thing to be doing in the afternoon.)
Hope this sheds some light on the subject of IMEI codes and their barcode representation.
Brad Barnhill
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|