VC实现二维码(qrcode)编码源码

二维码流行起来了,到处可见,好像报纸广告上面没个二维码就不上档次是的,所以好奇,略研究了一下,搜出了不少都是ZXING的C#版,或是java, 还有JS的,但暂没收到 VC MFC方面的,所以做个体力劳动,将java版的批量转换了一下, 望网友指正, 同时在我的资源下载中我提供一个DLL用于其它非MFC开发程序用:

二维码的关键点:

      数据表示:     全是数字的,0-9的数

                              数字与大字字母混合的

                             全是汉字或日文字的

                             以上三种都不是的,直接以8BIT字符来存数据

 

    容错等级:

                   H      是高           撕掉30%都无所谓,照读得出来 ,所以现在好多二维码中间搞了logo,很牛的样子

                   M       20%

                   Q    15%

                    L      5%

   版本:     1-40,    基本上1-10就够用了,本文暂实现1-10,要扩展只要增加定义就行

源码一个qrcode.h,一个qrcode.cpp, 

用法:

a)直接画在dc上 

 CQrcode *qrcode = CQrcode::getMinimumQRCode("http://www.csdn.net", ErrorCorrectLevel_H);
  qrcode->Draw(pDC, 4, 4);

b)保存为bmp图像:

CQrcode *qrcode = CQrcode::getMinimumQRCode("http://www.csdn.net", ErrorCorrectLevel_H);
qrcode->SaveToBmp("c:\\csdn.bmp", 4, 4);

 

//qrcode.h:

class CQrcodeBitBuffer 
{
public:
 void put(BOOL bit);
 void put(int num, int length);
 BOOL get(int index);
 CString toString();
 int getLengthInBits();
 BYTE* getBuffer();
 CQrcodeBitBuffer();
 virtual ~CQrcodeBitBuffer();
private:
 BYTE *buffer;
 int buffer_len;
 int length;
 int inclements;
};

class CQrcodePolynomial 
{
public:
 CQrcodePolynomial mod(CQrcodePolynomial &e);
 CQrcodePolynomial multiply(CQrcodePolynomial &e);
 CString toLogString();
 CString toString();
 int getLength();
 int get(int idx);
 //
 CQrcodePolynomial(CUIntArray& nums, int shift);
 CQrcodePolynomial(const CQrcodePolynomial &p);
 CQrcodePolynomial& operator=(const CQrcodePolynomial &p);

 virtual ~CQrcodePolynomial();

 CUIntArray m_nums;
};

class CQrcodeUtil 
{
public:
 static int unsignedRightShift(int v, int n);
 static int getBCHTypeNumber(int data);
 static int getBCHTypeInfo(int data);
 static int getBCHDigit(int data);
 static BOOL isHanZi(CString s);
 static BOOL isAlphaNum(CString s);
 static BOOL isNumber(CString s);
 static int getMode(CString s);
 static BOOL getMask(int maskPattern, int i, int j);
 static CQrcodePolynomial getErrorCorrectPolynomial(int errorCorrectLength);
 static void getPatternPosition(int typeNumber, CUIntArray &p);
 static int getMaxLength(int typeNumber, int mode, int errorCorrectLevel);

 CQrcodeUtil();
 virtual ~CQrcodeUtil();

};

 

class CQrcodeMath 
{
public:
 int gexp(int n);
 int glog(int n);

 static CQrcodeMath * getInstance();

 CQrcodeMath();
 virtual ~CQrcodeMath();


private:
 CUIntArray EXP_TABLE;
 CUIntArray LOG_TABLE;
};


class CQrcodeData  : public CObject
{
public:
 int getLengthInBits(int type);
 virtual void write(CQrcodeBitBuffer &buffer);
 virtual int getLength();

 int getMode();
 CQrcodeData(int mode, CString data);
 virtual ~CQrcodeData();

 CString data;

private:
 int mode;
};

class CQrcodeNumber : public CQrcodeData 
{
public:
 virtual void write(CQrcodeBitBuffer &buffer);
 int parseInt(CString s);
 CQrcodeNumber(CString data);
 virtual ~CQrcodeNumber();

};


 

class CQrcodeAlphaNum : public CQrcodeData 
{
public:
 int getCode(char c);
 virtual void write(CQrcodeBitBuffer &buffer);
 CQrcodeAlphaNum(CString data);
 virtual ~CQrcodeAlphaNum();

};

class CQrcodeHanzi : public CQrcodeData 
{
public:
 virtual void write(CQrcodeBitBuffer &buffer);
 virtual int getLength();
 CQrcodeHanzi(CString data);
 virtual ~CQrcodeHanzi();

};

 

class CQrcode8BitByte : public CQrcodeData 
{
public:
 virtual void write(CQrcodeBitBuffer &buffer);
 CQrcode8BitByte(CString data);
 virtual ~CQrcode8BitByte();

};

 

class CQrcode2DIntArray 
{
public:
 CUIntArray * GetIntArray(int r);
 int GetAt(int r,int c);
 void SetAt(int r,int c,int v);
 CQrcode2DIntArray();
 virtual ~CQrcode2DIntArray();
private:
 CObArray a;
};

 

class CQrcodeRSBlock  : public CObject
{
public:
 CQrcodeRSBlock(int totalCount, int dataCount);
 virtual ~CQrcodeRSBlock();

 int getDataCount();
 int getTotalCount();
 static void getRsBlockTable(int typeNumber, int errorCorrectLevel, CUIntArray &a);
 static void getRSBlocks(int typeNumber, int errorCorrectLevel, CObArray &RBSlocks);

private:
 int totalCount;
 int dataCount;

};


class CQrcode
{
public:
 void SaveToBmp(CString filename, int cellSize, int margin);
 void Draw(CDC *pdc,int cellSize, int margin);
 static CQrcode* getMinimumQRCode(CString data, int errorCorrectLevel);
 void mapData(BYTE* bytes,int bytes_size, int maskPattern);
 static BYTE* createData(int typeNumber, int errorCorrectLevel, CObArray &dataArray, int* bytesSize);
 static BYTE* createBytes(CQrcodeBitBuffer &buffer, CObArray &rsBlocks, int* bytesSize);
 void setupTypeNumber(BOOL test);
 void setupTypeInfo(BOOL test, int maskPattern);
 void setupTimingPattern();
 void setupPositionAdjustPattern();
 void setupPositionProbePattern(int row, int col);
 static int getLostPoint(CQrcode *qrcode);
 int getBestMaskPattern();
 void make();
 void make(BOOL test, int maskPattern);
 int getModuleCount();
 BOOL isDark(int row, int col);
 CQrcodeData * getData(int index);
 int getDataCount();
 void clearData();
 void addData(CString data, int mode);
 void addData(CString data);
 void setErrorCorrectLevel(int errorCorrectLevel);
 void setTypeNumber(int typeNumber);
 CQrcode();
 virtual ~CQrcode();

private:
 BYTE *modules;
 int moduleCount;
 int typeNumber;
 int errorCorrectLevel;
 CObArray qrDataList;

};

#define ErrorCorrectLevel_L  1
#define ErrorCorrectLevel_M  0
#define ErrorCorrectLevel_Q  3
#define ErrorCorrectLevel_H  2

 

//qrcode.cpp

#include "qrcode.h"

#define MODE_NUMBER  (1<<0)
#define MODE_ALPHA_NUM (1<<1)
#define MODE_8BIT_BYTE (1<<2)
#define MODE_HANZI (1<<3)
#define PATTERN000 0
#define PATTERN001 1
#define PATTERN010 2
#define PATTERN011 3
#define PATTERN100 4
#define PATTERN101 5
#define PATTERN110 6
#define PATTERN111 7
#define PAD0   0xEC
#define PAD1   0x11
#define G15 ((1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0))
#define G18 ((1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0))
#define G15_MASK ((1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1))

int RS_BLOCK_TABLE[40][6]  = {

  // L =1
  // M =0
  // Q =3
  // H =2

  // 1
  {1, 26, 19,0,0,0},
  {1, 26, 16,0,0,0},
  {1, 26, 13,0,0,0},
  {1, 26, 9,0,0,0},
 
  // 2
  {1, 44, 34,0,0,0},
  {1, 44, 28,0,0,0},
  {1, 44, 22,0,0,0},
  {1, 44, 16,0,0,0},

  // 3
  {1, 70, 55,0,0,0},
  {1, 70, 44,0,0,0},
  {2, 35, 17,0,0,0},
  {2, 35, 13,0,0,0},

  // 4 
  {1, 100, 80,0,0,0},
  {2, 50, 32,0,0,0},
  {2, 50, 24,0,0,0},
  {4, 25, 9,0,0,0},
 
  // 5
  {1, 134, 108,0,0,0},
  {2, 67, 43,0,0,0},
  {2, 33, 15, 2, 34, 16},
  {2, 33, 11, 2, 34, 12},
 
  // 6
  {2, 86, 68,0,0,0},
  {4, 43, 27,0,0,0},
  {4, 43, 19,0,0,0},
  {4, 43, 15,0,0,0},
 
  // 7 
  {2, 98, 78,0,0,0},
  {4, 49, 31,0,0,0},
  {2, 32, 14, 4, 33, 15},
  {4, 39, 13, 1, 40, 14},
 
  // 8
  {2, 121, 97,0,0,0},
  {2, 60, 38, 2, 61, 39},
  {4, 40, 18, 2, 41, 19},
  {4, 40, 14, 2, 41, 15},
 
  // 9
  {2, 146, 116,0,0,0},
  {3, 58, 36, 2, 59, 37},
  {4, 36, 16, 4, 37, 17},
  {4, 36, 12, 4, 37, 13},
 
  // 10 
  {2, 86, 68, 2, 87, 69},
  {4, 69, 43, 1, 70, 44},
  {6, 43, 19, 2, 44, 20},
  {6, 43, 15, 2, 44, 16}

 };

 

 int PATTERN_POSITION_TABLE[40][7] ={
  {0,0,0,0,0,0,0},
  {6, 18,0,0,0,0,0},
  {6, 22,0,0,0,0,0},
  {6, 26,0,0,0,0,0},
  {6, 30,0,0,0,0,0},
  {6, 34,0,0,0,0,0},
  {6, 22, 38,0,0,0,0},
  {6, 24, 42,0,0,0,0},
  {6, 26, 46,0,0,0,0},
  {6, 28, 50,0,0,0,0},
  {6, 30, 54,0,0,0,0}, 
  {6, 32, 58,0,0,0,0},
  {6, 34, 62,0,0,0,0},
  {6, 26, 46, 66,0,0,0},
  {6, 26, 48, 70,0,0,0},
  {6, 26, 50, 74,0,0,0},
  {6, 30, 54, 78,0,0,0},
  {6, 30, 56, 82,0,0,0},
  {6, 30, 58, 86,0,0,0},
  {6, 34, 62, 90,0,0,0},
  {6, 28, 50, 72, 94,0,0},
  {6, 26, 50, 74, 98,0,0},
  {6, 30, 54, 78, 102,0,0},
  {6, 28, 54, 80, 106,0,0},
  {6, 32, 58, 84, 110,0,0},
  {6, 30, 58, 86, 114,0,0},
  {6, 34, 62, 90, 118,0,0},
  {6, 26, 50, 74, 98, 122,0},
  {6, 30, 54, 78, 102, 126,0},
  {6, 26, 52, 78, 104, 130,0},
  {6, 30, 56, 82, 108, 134,0},
  {6, 34, 60, 86, 112, 138,0},
  {6, 30, 58, 86, 114, 142,0},
  {6, 34, 62, 90, 118, 146,0},
  {6, 30, 54, 78, 102, 126, 150},
  {6, 24, 50, 76, 102, 128, 154},
  {6, 28, 54, 80, 106, 132, 158},
  {6, 32, 58, 84, 110, 136, 162},
  {6, 26, 54, 82, 110, 138, 166},
  {6, 30, 58, 86, 114, 142, 170}
 };
 int MAX_LENGTH[10][4][4] = {
      //L N   A    8B  Han           M                         Q                     H
        { {41,  25,  17,  10},  {34,  20,  14,  8},   {27,  16,  11,  7},  {17,  10,  7,   4} },
        { {77,  47,  32,  20},  {63,  38,  26,  16},  {48,  29,  20,  12}, {34,  20,  14,  8} },
        { {127, 77,  53,  32},  {101, 61,  42,  26},  {77,  47,  32,  20}, {58,  35,  24,  15} },
        { {187, 114, 78,  48},  {149, 90,  62,  38},  {111, 67,  46,  28}, {82,  50,  34,  21} },
        { {255, 154, 106, 65},  {202, 122, 84,  52},  {

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值