You are on page 1of 8

using

using
using
using
using
using

System;
System.Collections.Generic;
System.Text;
System.Drawing;
System.Drawing.Drawing2D;
System.Drawing.Imaging;

namespace BarCodeEan13
{
class Ean13
{
#region Static initialization
static Dictionary<int, Pattern> codes = new Dictionary<int, Pattern>();
static Dictionary<int, Parity> parity = new Dictionary<int, Parity>();
static Ean13()
{
//
#
AddCode(0,
AddCode(1,
AddCode(2,
AddCode(3,
AddCode(4,
AddCode(5,
AddCode(6,
AddCode(7,
AddCode(8,
AddCode(9,

LEFT ODD
"0001101",
"0011001",
"0010011",
"0111101",
"0100011",
"0110001",
"0101111",
"0111011",
"0110111",
"0001011",

AddParity(0,
AddParity(1,
AddParity(2,
AddParity(3,
AddParity(4,
AddParity(5,
AddParity(6,
AddParity(7,
AddParity(8,
AddParity(9,

LEFT EVEN
"0100111",
"0110011",
"0011011",
"0100001",
"0011101",
"0111001",
"0000101",
"0010001",
"0001001",
"0010111",

RIGHT
"1110010");
"1100110");
"1101100");
"1000010");
"1011100");
"1001110");
"1010000");
"1000100");
"1001000");
"1110100");

"ooooo");
"oeoee");
"oeeoe");
"oeeeo");
"eooee");
"eeooe");
"eeeoo");
"eoeoe");
"eoeeo");
"eeoeo");

}
static void AddCode(int digit, string lhOdd, string lhEven, string rh)
{
Pattern p = new Pattern();
p.LhOdd = lhOdd; p.LhEven = lhEven; p.Rh = rh;
codes.Add(digit, p);
}
static void AddParity(int digit, string par)
{
parity.Add(digit, new Parity(par));
}
#endregion
private Ean13Settings settings;
private string code;
private string title;

public Ean13(string code, string title)


: this(code, title, new Ean13Settings())
{
}
public Ean13(string code, string title, Ean13Settings settings)
{
this.settings = settings;
this.code = code;
this.title = title;
if (!CheckCode(code))
throw new ArgumentException("Invalid EAN-13 code specified.");
}
private bool CheckCode(string code)
{
if (code == null || code.Length != 13)
return false;
int res;
foreach (char c in code)
if (!int.TryParse(c.ToString(), out res))
return false;
char check = (char)('0' + CalculateChecksum(code.Substring(0, 12)));
return code[12] == check;
}
public static int CalculateChecksum(string code)
{
if (code == null || code.Length != 12)
throw new ArgumentException("Code length should be 12, i.e. excl
uding the checksum digit");
int sum = 0;
for (int i = 0; i < 12; i++)
{
int v;
if (!int.TryParse(code[i].ToString(), out v))
throw new ArgumentException("Invalid character encountered i
n specified code.");
sum += (i % 2 == 0 ? v : v * 3);
}
int check = 10 - (sum % 10);
return check % 10;
}
private int top;
public Image Paint()
{
top = settings.TopMargin;
Graphics g = Graphics.FromImage(new Bitmap(1, 1));
int width = (3 + 6 * 7 + 5 + 6 * 7 + 3) * settings.BarWidth + settin
gs.LeftMargin + settings.RightMargin + (int)g.MeasureString(code[0].ToString(),
settings.Font).Width;

int height = settings.BarCodeHeight;


if (title != null)
{
int h = (int)g.MeasureString(title, settings.Font).Height;
height += h;
top += h;
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
g = Graphics.FromImage(bmp);
int left = settings.LeftMargin;
//LEFT GUARD
left = DrawLeftGuard(settings, g, code[0].ToString(), left);
//LEFT GROUP
int first = int.Parse(code[0].ToString());
Parity par = parity[first];
string digit = code[1].ToString();
left = Draw(settings, g, left, digit, codes[int.Parse(digit)].LhOdd)
; //Odd
for (int i = 2; i <= 6; i++)
{
digit = code[i].ToString();
Pattern p = codes[int.Parse(digit)];
left = Draw(settings, g, left, digit, (par.IsOdd(i - 2) ? p.LhOd
d : p.LhEven));
}
//MIDDLE GUARD
left = DrawCenterGuard(settings, g, left);
//RIGHT GROUP
for (int i = 7; i <= 12; i++)
{
digit = code[i].ToString();
Pattern p = codes[int.Parse(digit)];
left = Draw(settings, g, left, digit, p.Rh);
}
//RIGHT GUARD
left = DrawRightGuard(settings, g, left);
return bmp;
}
private static Pen pen = new Pen(Color.Black);
private static Brush brush = Brushes.Black;
private int Draw(Ean13Settings settings, Graphics g, int left, string di
git, string s)
{
int h = (int)(settings.BarCodeHeight * 0.8);
g.DrawString(digit, settings.Font, brush, left, h + top);
foreach (char c in s)
{

if (c == '1')
g.FillRectangle(brush, left, top, settings.BarWidth, h);
left += settings.BarWidth;
}
return left;
}
private int DrawLeftGuard(Ean13Settings settings, Graphics g, string dig
it, int left)
{
int h = (int)(settings.BarCodeHeight * 0.8);
g.DrawString(digit, settings.Font, brush, left, h + top);
left += (int)g.MeasureString(digit, settings.Font).Width;
//TITLE
if (title != null)
g.DrawString(title, settings.Font, brush, left, settings.TopMarg
in);
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;
left += settings.BarWidth;
//0
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;
return left;
}
private int DrawRightGuard(Ean13Settings settings, Graphics g, int left)
{
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;
left += settings.BarWidth;
//0
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;
return left;
}
private int DrawCenterGuard(Ean13Settings settings, Graphics g, int left
)
{
left += settings.BarWidth;
//0
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;

left += settings.BarWidth;
//0
g.FillRectangle(brush, left, top, settings.BarWidth, settings.BarCod
eHeight); //1
left += settings.BarWidth;
left += settings.BarWidth;
//0
return left;
}
class Pattern
{
private string lhOdd;
public string LhOdd
{
get { return lhOdd; }
set { lhOdd = value; }
}
private string lhEven;
public string LhEven
{
get { return lhEven; }
set { lhEven = value; }
}
private string rh;
public string Rh
{
get { return rh; }
set { rh = value; }
}
}
class Parity
{
private string par;
internal Parity(string par)
{
this.par = par;
}
internal bool IsOdd(int i)
{
return par[i] == 'o';
}
internal bool IsEven(int i)
{
return par[i] == 'e';
}
}

}
class Ean13Settings
{
private int height = 120;
public int BarCodeHeight
{
get { return height; }
set { height = value; }
}
private int leftMargin = 10;
public int LeftMargin
{
get { return leftMargin; }
set { leftMargin = value; }
}
private int rightMargin = 10;
public int RightMargin
{
get { return rightMargin; }
set { rightMargin = value; }
}
private int topMargin = 10;
public int TopMargin
{
get { return topMargin; }
set { topMargin = value; }
}
private int bottomMargin = 10;
public int BottomMargin
{
get { return bottomMargin; }
set { bottomMargin = value; }
}
private int barWidth = 2;
public int BarWidth
{
get { return barWidth; }
set { barWidth = value; }
}
private Font font = new Font(FontFamily.GenericSansSerif, 10);
internal Font Font
{
get { return font; }
}
}

class Program
{
static void Main(string[] args)
{
/*
//string isbn = "0-7356-1917-4";
string isbn = "90 261 1455 9";
bool valid = CheckIsbn(isbn);
if (!valid)
throw new Exception();
string code = IsbnToEan13(isbn);
Ean13 barcode = new Ean13(code, "ISBN " + isbn);
*/
//Ean13 barcode = new Ean13("5028421973326", null);
Ean13 barcode = new Ean13("4009900409537", null);
barcode.Paint().Save("c:\\temp\\test.png", ImageFormat.Png);
}
static bool CheckIsbn(string isbn)
{
if (isbn == null)
return false;
isbn = NormalizeIsbn(isbn);
if (isbn.Length != 10)
return false;
int res;
for (int i = 0; i < 9; i++)
if (!int.TryParse(isbn[i].ToString(), out res))
return false;
int sum = 0;
for (int i = 0; i < 9; i++)
sum += (i + 1) * int.Parse(isbn[i].ToString());
int r = sum % 11;
if (r == 10)
return isbn[9] == 'X';
else
return isbn[9] == (char)('0' + r);
}
static string IsbnToEan13(string isbn)
{
isbn = NormalizeIsbn(isbn);
string code = "978" + isbn.Substring(0, 9);
code += (char)('0' + Ean13.CalculateChecksum(code));
return code;
}

static string NormalizeIsbn(string isbn)


{
return isbn.Replace("-", "").Replace(" ", "").Trim();
}
}
}

You might also like