Leptonica provides us with easy way to read barcodes but it does not offer a way to create them(as far as I know). Here is a leptonica function that will allow us to generate CODABAR barcode, in the feature I am planning on adding more type and more options but for now this was all I needed.
Sample Usage
l_int32 res = 300;
l_int32 bar_width = .02 * res;
l_int32 bar_height = .35 * res;
// Barcode is bitonal
PIX* barcode= pixCreateBarcodeCodebar("C3853110009C", bar_width, bar_height, 10, 10, 2, 2);
if (barcode == NULL)
{
printf("\n******** ERROR ***********");
return;
}
pixWritePng("c:/temp/barcode.png", barcode, 0);
Implementation
/**
* Barcode Generator
* @author : greg
*/
#ifndef CREATEBARCODE_H_
#define CREATEBARCODE_H_
#include
#if !defined(LEPTONICA_ALLHEADERS_H)
# include
#endif
#if !defined(LEPTONICA_READBARCODE_H)
# include
#endif
/* ----------------------------------------------------------------- *
* Codabar symbology *
* Data B S B S B S B Value
* 0 0 0 0 0 0 1 1 0
* 1 0 0 0 0 1 1 0 1
* 2 0 0 0 1 0 0 1 2
* @ref http://www.barcodesymbols.com/codabar.htm
* @ref leptonica/readbarcode.h
* ----------------------------------------------------------------- */
static const char *CodabarCodes[] =
{ "1111122", "1111221", "1112112", "2211111", "1121121", /* 0: 0 - 4 */
"2111121", "1211112", "1211211", "1221111", "2112111", /* 5: 5 - 9 */
"1112211", "1122111", "2111212", "2121112", "2121211", /* 10: -,$,:,/,. */
"1121212", "1122121", "1212112", "1112122", "1112221" /* 15: +,A,B,C,D */
};
int mapCodebarToIndex(const char c)
{
switch (toupper(c))
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return atoi(&c);
case '-':
return 10;
case '$':
return 11;
case ':':
return 12;
case '/':
return 13;
case '.':
return 14;
case '+':
return 15;
case 'A':
return 16;
case 'B':
return 17;
case 'C':
case '*':
return 18;
case 'E':
case 'D':
return 19;
}
return 0;
}
/**
* Crate 8 bpp Codebar barcode
*/
PIX* pixCreateBarcodeCodebar(const char* code, l_int32 bar_width, l_int32 bar_height, l_int32 margin_left,
l_int32 margin_right, l_int32 margin_top, l_int32 margin_bottom)
{
PROCNAME("pixCreateBarcodeCodebar");
printf("\n Rendering : %s", code);
//The width ratio between narrow and wide can be chosen between 1:2.25 and 1:3
l_float32 ratio = 2;
l_int32 width_wide = bar_width * ratio;
l_int32 narrow_space = bar_width;
// Calculate size
l_int32 size = 0;
for (int i = 0; code[i] != '\0'; ++i, ++size)
{
// NOOP
}
// allocate big enough image
PIX* pix = pixCreate(size * width_wide * 7, bar_height, 1);
pixSetResolution(pix, 300, 300);
l_int32 xpos = margin_left;
for (int i = 0; i < size; ++i)
{
const char* encoding = CodabarCodes[mapCodebarToIndex(code[i])];
for (l_uint16 j = 0; j < 7; j++)
{
l_int32 renderwidth = bar_width;
if (encoding[j] == '2')
{
renderwidth = width_wide;
}
if ((j % 2 == 0))
{
for (l_int32 k = 0; k < renderwidth; ++k)
{
// pixRenderLineArb(pix, xpos+k, 0, xpos+k, height, 1, 0, 0, 0);
pixRenderLine(pix, xpos + k, margin_top, xpos + k, bar_height - margin_bottom, 1, L_SET_PIXELS);
}
}
xpos += renderwidth;
}
// Each character is separated by narrow space
if (i < size - 1)
xpos += narrow_space;
}
// Clip
BOX* bounds = boxCreate(0, 0, xpos + margin_right, bar_height);
pix = pixClipRectangle(pix, bounds, NULL);
boxDestroy(&bounds);
return pix;
}
#endif /* CREATEBARCODE_H_ */
I think I will make this my first GIT project and share it with all, trying to move away from google code.
Leave a Reply