【C语言版】
QR.EXE更新至1.2版, 增加二维码超窗显示,外加最小体积图片输出。代码做了高度优化,方便批量生产。
笔名由HAPPY改为LEO,以便统一不同论坛的作品笔名。
下载:http://bcn.bathome.net/s/tool/index.html?key=qr
核心代码:- /*
- CONSOLE QRCODE, COPYRIGHT@2017~2019 BY LEO, VERSION 1.2
- QR.EXE
- LINK GDI32 GDIPLUS
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <gdiplus\gdiplus.h>
- #include "QR_Encode.cpp"
-
- //GDI+命名空间
- using namespace Gdiplus;
-
- #define BF_ZOOM 10
- #define BF_MARGIN 10
-
- //定义帮助说明
- #define HELP_INFORMATION "\
- QR version 1.2 - Console qrcode tool - Copyright (C) 2017-2019 by Leo\n\
- \n\
- Usage:\n\
- qr [your text] [outfile name]\n\
- \n\
- Official website:\n\
- http://www.bathome.net/thread-44095-1-1.html\n"
-
- //声明C函数
- extern "C" HWND WINAPI GetConsoleWindow();
-
- //转码款字符
- WCHAR* LW(const CHAR* str)
- {
- if(!str){return NULL;}
- int wLen=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0);
- WCHAR* wstr=(WCHAR*)malloc(sizeof(WCHAR)*wLen + 1);
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, wLen);
- wstr[wLen]='\0';
- return wstr;
- }
-
- //获取编码器CLSID
- BOOL GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
- {
- UINT j, n=0, s=0;
- ImageCodecInfo* pInfo=NULL;
- GetImageEncodersSize(&n, &s);
- if(s==0)
- {
- return FALSE;
- }
- pInfo=(ImageCodecInfo*)(malloc(s));
- if(pInfo==NULL)
- {
- return FALSE;
- }
- GetImageEncoders(n, s, pInfo);
- for(j=0; j<n; j++)
- {
- if(wcscmp(pInfo[j].MimeType, format)==0)
- {
- *pClsid=pInfo[j].Clsid;
- free(pInfo);
- return TRUE;
- }
- }
- free(pInfo);
- return FALSE;
- }
-
- //主函数入口
- int main(int argc, char* argv[])
- {
- if(argc!=2 && argc!=3)
- {
- fprintf(stdout, HELP_INFORMATION);
- return 1;
- }
-
- //初始化GDI+
- GdiplusStartupInput gdiplusstartupinput;
- ULONG_PTR gdiplustoken;
- GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
-
- {
- char *pCodeStr=argv[1];
- CQR_Encode* pQR_Encode = new CQR_Encode;
-
- //生成QR二维码数据
- if (! pQR_Encode->EncodeData(QR_LEVEL_H, QR_VRESION_S, TRUE, -1, pCodeStr))
- {
- fprintf(stdout, "Encode data error\n");
- return 1;
- }
-
- //根据生成的QR二进制数据 建立图片的长宽
- int qwith=pQR_Encode->m_nSymbleSize*BF_ZOOM+BF_MARGIN*2, qhigh=pQR_Encode->m_nSymbleSize*BF_ZOOM+BF_MARGIN*2;
-
- //建立位图文件
- Rect qrect(0, 0, qwith, qhigh);
- Bitmap* tbmp=new Bitmap(qwith, qhigh, PixelFormat24bppRGB);
- BitmapData* pBitmapData = new BitmapData;
- //并锁定位图二进制信息
- tbmp->LockBits(&qrect, ImageLockModeRead, PixelFormat24bppRGB, pBitmapData);
- BYTE *pByte = (BYTE *)pBitmapData->Scan0;
- int iOffset = pBitmapData->Stride - qwith*3;
-
- //遍历位图每个点
- for(int i=0; i <qwith; i++)
- {
- for(int j=0; j <qhigh; j++)
- {
- //如果位图中的点满足填充白色,则将该点像素值设为RGB(255,255,255)
- if(i<BF_MARGIN || i>=qwith-BF_MARGIN || j<BF_MARGIN || j>=qhigh-BF_MARGIN || !pQR_Encode->m_byModuleData[(i-BF_MARGIN)/BF_ZOOM][(j-BF_MARGIN)/BF_ZOOM])
- {
- pByte[0] = 255;
- pByte[1] = 255;
- pByte[2] = 255;
- }
- pByte+=3;
- }
- pByte += iOffset;
- }
- //解除锁定
- tbmp->UnlockBits(pBitmapData);
-
- //建立单值位图sbmp,并进行位图拷贝
- Bitmap* sbmp=tbmp->Clone(qrect, PixelFormat1bppIndexed);
-
- //在控WIN制台显示QR图片
- if(argc==2)
- {
- Graphics* graph=new Graphics(GetDesktopWindow());
- graph->DrawImage(sbmp, qrect);
- DeleteObject(graph);
- }
- else
- {
-
- //对位图sbmp进行编码,并输出为png格式
- CLSID clsid;
- if(GetEncoderClsid(L"image/png", &clsid))
- {
- if(sbmp->Save(LW(argv[2]), &clsid, NULL) != S_OK)
- {
- fprintf(stdout, "Save image failed\n");
- return 1;
- }
- }
- else
- {
- fprintf(stdout, "Encode image failed\n");
- return 1;
- }
- }
-
- //释放内存
- delete pQR_Encode;
- delete pBitmapData;
- delete tbmp;
- delete sbmp;
- }
-
- //关闭GDI+
- GdiplusShutdown(gdiplustoken);
- return 0;
- }
复制代码 .
.
【Python版】
脚本代码:- #-*- encoding:utf-8 -*-
- # Made by Happy
-
- # 导入QR模块
- import qrcode
- import image
- import getopt,sys
-
- def QR_Encode(text):
-
- qr=qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=10, border=1)
- qr.add_data(text)
- qr.make(fit=True)
- return qr.make_image()
-
- def main():
-
- tv="";ov="";flag=False
-
- ops,avs = getopt.getopt(sys.argv[1:], "ht:so:r:", ["help", "text", "show", "out", "recognise"])
-
- if len(sys.argv) == 1:
- print("Usage: pqr [-t text] [-o outfile] [-s show image]")
- sys.exit(1)
-
- for op,av in ops:
-
- if op in ("-h", "--help"):
- print("Usage: pqr [-t text] [-o outfile] [-s show image]")
- sys.exit(0)
-
- elif op in ("-t","--text"):
- tv=av
-
- elif op in ("-o","--out"):
- ov=av
-
- elif op in ("-s","--show"):
- flag=True
-
- else:
- print("Unrecognise options '%s'" %av)
- sys.exit(1)
-
- if not tv in '':
-
- img=QR_Encode(tv)
-
- if not ov in '':
- img.save(ov)
-
- if flag is True:
- img.show()
- else:
- print("Please input text string")
- sys.exit(1)
- main()
复制代码 使用方法:- Usage: pqr [-t text] [-o outfile] [-s show image]
- Example:
- pqr -t 你好 -o 3.png
复制代码 pqr支持的二维码汉字容量惊人,生成的图片体积极小、清晰度极高、容错识别极强。且pqr.exe比C语言版qr.exe功能多,可直接显示二维码,安装响应模块,可支持多种特殊功能。安装zbar库,还能支持条码识别,py脚本请参看15楼。 |