I read this kind of funny story about a kid who got himself into a little trouble reading and writing barcodes by hand. After reading it, I figured if he's going through the trouble of getting graph paper and markers to write Code 39, I can certainly provide the code to doing it with DotImage.

Code 39 is a simple barcode format -- it supports only capital letters, numbers, and seven other special characters (so 43 characters total). Each letter is encoded with nine alternating black and white bars, always starting and ending with black. Three of the nine bars will be wide, and the rest narrow (thus the name -- sometimes also called 3 of 9). Between each letter is a narrow white bar, and there is a start and stop code so you know that you are looking at a Code 39.

One nice thing about Code 39 is that you can calculate the size in pixels before encoding, since each letter is the same size (3 wide and 6 narrow).

Here's some code:

First I grabbed the table of encodings from the wikipedia page on Code 39 and put them into a hashtable:

private static Hashtable _encoding = new Hashtable();

static BarcodeCode39()
{
_encoding['*'] = "bWbwBwBwb";
_encoding['-'] = "bWbwbwBwB";

// rest of encodings removed

Here is how you calculate the width of the image (there are two extra characters added to the barcode, and I have a margin as well).

public int ImageWidth
{
get
{
return (_data.Length + 2) * ((3 * _wideWidth) + (6 * _narrowWidth)) +
(_data.Length+1) * _narrowWidth +
2 * _margin;
}
}

To make the barcode, I create the image:

int imageWidth = ImageWidth;

AtalaImage barcodeImg = new AtalaImage(imageWidth, _imageHeight, pf, Color.White);
Canvas barcodeCanvas = new Canvas(barcodeImg);
Fill fill = new SolidFill(Color.Black);
AtalaPen pen = new AtalaPen(Color.Black);

Then here is my main loop through the data to encode:

string dataToEncode = "*" + _data + "*";
int x = _margin;
foreach (char c in dataToEncode)
{
string bars = (string)_encoding[c];
if (bars == null)
{
throw new NotSupportedException("Invalid character in data: '"+c+"'");
}

foreach (char b in bars)
{
switch (b)
{
case 'B': // Wide Black
barcodeCanvas.DrawRectangle(new Rectangle(x, _margin, _wideWidth, _imageHeight-2*_margin), pen, fill);
x += _wideWidth;
break;
case 'W': // Wide White
x += _wideWidth;
break;
case 'b': // Narrow Black
barcodeCanvas.DrawRectangle(new Rectangle(x, _margin, _narrowWidth, _imageHeight-2*_margin), pen, fill);
x += _narrowWidth;
break;
case 'w': // Narrow White
x += _narrowWidth;
break;
}
}
x += _narrowWidth; // between characters
}

I attached Assemblies built off of DotImage 6.0 -- if you have a maintenance release (you are reading this after 6.0a has been released), you can find a version of this in the Demo directories.

Here's how you use it:

BarcodeCode39 bc39 = new BarcodeCode39(data);
bc39.Margin = 1;
AtalaImage img = bc39.CreateBarcodeImage(PixelFormat.Pixel24bppBgr);

Then, you can use the image to overlay onto another with OverlayCommand. There are properties to adjust the outcome (NarrowWidth, WideWidth, ImageHeight, Margin).

Here's how you recognize that barcode with the Atalasoft Barcode Reader: