views:

382

answers:

2

I am writing a barcode application for work, where I create a graphics object and draw the various bars for a code 39 barcode. I create the graphics object with the following code:

int reqBarcodeWidth = 100; int reqBarcodeHeight = 40;

objBitmap = new Bitmap(reqBarcodeWidth, reqBarcodeHeight);

objGraphics = Graphics.FromImage(objBitmap);

One of the things I want to do, however, is to allow different units to be used for drawing onto the graphics object, for example:

objGraphics.PageUnit = GraphicsUnit.Inch;

If I do this however, how do I know what size of bitmap to create in order to fit the full barcode on it?

Thanks in advance for any help.

Update:

Thanks for the reply. I have looked at barcode fonts before and really want to do away with installing fonts on many machines.

Also one of the functions of the program, which I didn't mention, will be to print stock codes for the warehouse which don't have EAN codes associated with them. These are typically items from China with complex stock codes. These will need to use a Code 128 barcode which use the extended range of characters and also take up less space.

The hard bit is mostly done its just the creation of the image I need to sort out. I don't know if I am trying to do this a complicated way, not really done any work on images before.

+1  A: 

Do you know that exists fonts that draw barcode, so you can avoid all this mess???

gbianchi
A: 

If I do this however, how do I know what size of bitmap to create in order to fit the full barcode on it?

Bitmaps are based on physical devices which have certain resolutions usually measured in DPI (dots per inch). The Windows OS assigs a logical resolution of 96 or 120 dpi to a monitor. Printers have a physical resolution of 300 - 600 and sometimes up to 1200 or more. Imagesetters which process film can have physical resolutions up to 2540 or more DPI.

A logical resolution implies that X dots are equal to one inch on a certain device. Usually this is an approximation and can be used for zooming. A physical resolution indicates that the device can realize (or there are physically present) X number of dots per inch.

When making barcodes and printing to a device you must take into account the resolution of that device. If you have a barcode that is 4 inches wide and want to print it on a 600 dpi printer, you would need a bitmap 4 * 600 = 2400 pixels wide. There are other ramifications to printing on certain devices so that you don't inadvertently downsize/upsize the bars of the code.

The point of all my rambling is that you should generate your barcodes using a vector format such as .WMF or .EMF and then render that to a bitmap which is tailored to the device you want to output to. This will also allow you to edit the codes in a vector drawing program such as CorelDRAW or Adobe Illustrator.

Most if not all barcodes have a width formula that will tell you the width in inches of the final code given a certain encodation (symbology encoded in the barcode).

Having that bit of knowledge you can make barcodes using something similar to the following (copy and paste this vb.net code into a form.load or button click event of a new project):


Dim gfx As Graphics = Me.CreateGraphics
Dim hdc As IntPtr = gfx.GetHdc()
Dim mf As System.Drawing.Imaging.Metafile = New Imaging.Metafile("c:\1.wmf", hdc, New RectangleF(0, 0, 5 * 2540, 1 * 2540), Imaging.MetafileFrameUnit.GdiCompatible)
Dim g As Graphics = Graphics.FromImage(mf)
g.PageUnit = GraphicsUnit.Inch

g.FillRectangle(Brushes.Blue, New RectangleF(0, 0, 5, 1))
g.FillRectangle(Brushes.Red, New RectangleF(0.25, 0.25, 4.5, 0.5))

g.Dispose()
mf.Dispose()
gfx.ReleaseHdc(hdc)
gfx.Dispose()
  • The dimension in the metafile constructor is inches * 2540. 2540 is a constant representing the .01 millimeters per inch. It's what the underlying GDI uses.

Now open "1.wmf" file with a real vector graphics program like CorelDRAW or Illustrator. (You can't use MSPaint or Windows Preview etc...) You will notice that you have a 5x1 blue rectangle with a 4.5 x 0.5 red rectangle centered inside.

This is how your barcodes should be drawn into a metafile. Replace the blue and red rectangle code with your barcode drawing routine. Don't forget to create a transparent sizing frame to tell the metafile the bounds of your drawing.


g.FillRectangle(Brushes.Transparent, rectBounds)

After you have your barcode drawn and saved to the metafile you can load it using GDI+ and render it to a bitmap that has the resolution of your output device. Obviously the final step is to send the bitmap to your output device, unless of course your output device has a vector or postscript processor built in.

Well, that was probably more than you ever wanted to know about the topic, but it is the right the way to do it and it will save you great amounts of time and heartache should your codes ever be accused of being 'unscannable'...

Good luck and let me know how it turns out.