Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drawing an EAN13 barcode

0.00/5 (No votes)
18 Oct 2005 1  
Drawing an EAN13 barcode based on Neil Van Eps' and Rainman_63's articles.

Introduction

I am very interested in Neil Van Eps' series of articles that shows how to draw barcodes. And I have been waiting for his next article since I had found his stuff on CodeProject. Actually, I need the articles for EAN8/13, UPCA/B. I searched in CodeProject, and found "Creating EAN-13 Barcodes with C#", by rainman_63. It's really helpful for me to understand clearly how to decode EAN barcodes.

Background

I am not familiar with C#, and C/C++ is a unique language that I had known. So I was very confused to research rainman_63's C# project. However, his detailed guiding was enough for me to implement an EAN13 project with Visual C++. In this article, I shall not explain how the EAN13 encoding works, for further information, you can read rainman_63's article "Creating EAN-13 Barcodes with C#".

CEAN13 Class

My CEAN13 is based on the CBarcode class, that has been introduced in Neil Van Eps' series of articles. See the class declaration below.

class CBarcode
{
    public:
        CBarcode();
        void LoadData(CString csMessage, double dNarrowBar, double dFinalHeight, 
                      HDC pDC, int nStartingXPixel, int nStartingYPixel, 
                      double dRatio = 1.0);
        virtual void DrawBitmap() = 0;
        virtual void BitmapToClipboard() = 0;
        virtual ~CBarcode();
        long GetBarcodePixelWidth();
        long GetBarcodePixelHeight();
    protected:
        CString m_csMessage;
        HDC m_hDC;
        long m_nFinalBarcodePixelWidth;
        long m_nNarrowBarPixelWidth;
        long m_nPixelHeight;
        long m_nStartingXPixel;
        long m_nStartingYPixel;
        long m_nSymbology;
        long m_nWideBarPixelWidth;
        virtual void DrawPattern(CString csPattern) = 0;
};

And here is the CEAN13 class declaration. It's implemented to draw an EAN13 barcode.

class CEAN13 : public CBarcode  
{
public:
    CEAN13();
    virtual ~CEAN13();
    void LoadData(CString csMessage, double dNarrowBar, 
         double dFinalHeight, long nGuardbarHeight, HDC hDC, int 
         nStartingXPixel, int nStartingYPixel, double dRatio);
    void DrawBitmap();
    void BitmapToClipboard();
    long CalculateCheckSumDigit();

private:
    long  m_nGuardbarHeight;
    CString RetrieveLeftOddParityPattern(int iNumber);
    CString RetrieveLeftEvenParityPattern(int iNumber);
    CString RetrieveRightPattern(int iNumber);
    CString RetrieveCountryCodePattern(int iNumber);

    void DrawPattern(CString csPattern);
};

Guard Bar

The UPC/EAN/JAN standards include specifications for some of the bars to extend below the main body of the bar code. These are called "guard" or "security" bars.

Using the CEAN13 Class

HDC hDC = GetDC()->m_hDC;
double dHeight = 1.5;
nGuardbarHeight = 20;
double dRatio = 3.0;
CEAN24 CodeEAN13;
CodeEAN13.LoadData(strMessage,0.02,dHeight,
          nGuardbarHeight,hDC,0,0,dRatio);
CodeEAN13.DrawBitmap();

CEAN13::DrawBitmap() Details

The DrawBitmap() function draws all the characters of the message. It divides a message into five parts and draws each part in turn.

  • Part 1: left quite zone and lead.
  • Part 2: country code and manufacture code.
  • Part 3: separator bars.
  • Part 4: product code.
  • Part 5: trailer and right quite zone.
void CEAN13::DrawBitmap()
{
    int i, tmpGuardBarHeight;
    
    DrawPattern("sssssssss"); // draw quite zone

    
    DrawPattern("bsb"); // draw lead


    CString strCountryCodePattern;
    strCountryCodePattern = RetrieveCountryCodePattern((int)m_csMessage.GetAt(0)-48);

    tmpGuardBarHeight = m_nGuardbarHeight;
    m_nGuardbarHeight = 0;
    
    DrawPattern(RetrieveLeftOddParityPattern((int)m_csMessage.GetAt(1)-48));
    
    for (i = 2 ; i < 7 ; i ++){
        if (strCountryCodePattern[i-2] == 'O')
            DrawPattern(RetrieveLeftOddParityPattern((int)m_csMessage.GetAt(i)-48));

        if (strCountryCodePattern[i-2] == 'E')
            DrawPattern(RetrieveLeftEvenParityPattern((int)m_csMessage.GetAt(i)-48));
    }

    m_nGuardbarHeight = tmpGuardBarHeight;

    DrawPattern("sbsbs"); // draw separator bars


    tmpGuardBarHeight = m_nGuardbarHeight;
    m_nGuardbarHeight = 0;
    for (i = 7 ; i < 12 ; i ++)
        DrawPattern(RetrieveRightPattern((int)m_csMessage.GetAt(i)-48));

    DrawPattern(RetrieveRightPattern(CalculateCheckSumDigit()));
    m_nGuardbarHeight = tmpGuardBarHeight;
    
    DrawPattern("bsb"); // draw trailer bars

    DrawPattern("sssssssss"); // draw quite zone 

}

Conclusion

My coding could not be nice ... ;=) but I tried my best to inherit from Neil Van Eps' and rainman_63's articles. I joined CodeProject 2 years ago, but have not contributed anything. It's time to do something for my favorite website. I would like to thank Neil Van Eps and rainman_63, your contributions were very helpful for me, and for everybody who would be interested in barcode topics. Thanks for any feedback.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here