找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 54508|回复: 16

[其他] 控制台二维码生成显示qr.exe

[复制链接]
发表于 2017-5-11 21:50:26 | 显示全部楼层 |阅读模式
【C语言版】
QR.EXE更新至1.2版, 增加二维码超窗显示,外加最小体积图片输出。代码做了高度优化,方便批量生产。
笔名由HAPPY改为LEO,以便统一不同论坛的作品笔名。
下载:http://bcn.bathome.net/s/tool/index.html?key=qr
核心代码:
  1. /*
  2.         CONSOLE QRCODE, COPYRIGHT@2017~2019 BY LEO, VERSION 1.2
  3.         QR.EXE
  4.         LINK GDI32 GDIPLUS
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <gdiplus\gdiplus.h>
  10. #include "QR_Encode.cpp"

  11. //GDI+命名空间
  12. using namespace Gdiplus;

  13. #define BF_ZOOM        10
  14. #define BF_MARGIN 10

  15. //定义帮助说明
  16. #define HELP_INFORMATION "\
  17. QR version 1.2 - Console qrcode tool - Copyright (C) 2017-2019 by Leo\n\
  18. \n\
  19. Usage:\n\
  20.     qr [your text] [outfile name]\n\
  21. \n\
  22. Official website:\n\
  23.     http://www.bathome.net/thread-44095-1-1.html\n"

  24. //声明C函数
  25. extern "C" HWND WINAPI GetConsoleWindow();

  26. //转码款字符
  27. WCHAR* LW(const CHAR* str)
  28. {
  29.         if(!str){return NULL;}
  30.         int wLen=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0);
  31.         WCHAR* wstr=(WCHAR*)malloc(sizeof(WCHAR)*wLen + 1);
  32.         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, wLen);
  33.         wstr[wLen]='\0';
  34.         return wstr;
  35. }

  36. //获取编码器CLSID
  37. BOOL GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
  38. {
  39.         UINT j, n=0, s=0;
  40.         ImageCodecInfo* pInfo=NULL;
  41.         GetImageEncodersSize(&n, &s);
  42.         if(s==0)
  43.         {
  44.                 return FALSE;
  45.         }
  46.         pInfo=(ImageCodecInfo*)(malloc(s));
  47.         if(pInfo==NULL)
  48.         {
  49.                 return FALSE;
  50.         }
  51.         GetImageEncoders(n, s, pInfo);
  52.         for(j=0; j<n; j++)
  53.         {
  54.                 if(wcscmp(pInfo[j].MimeType, format)==0)
  55.                 {
  56.                         *pClsid=pInfo[j].Clsid;
  57.                         free(pInfo);
  58.                         return TRUE;
  59.                 }
  60.         }
  61.         free(pInfo);
  62.         return FALSE;
  63. }

  64. //主函数入口
  65. int main(int argc, char* argv[])
  66. {
  67.         if(argc!=2 && argc!=3)
  68.         {
  69.                 fprintf(stdout, HELP_INFORMATION);
  70.                 return 1;
  71.         }

  72.         //初始化GDI+
  73.         GdiplusStartupInput gdiplusstartupinput;
  74.         ULONG_PTR gdiplustoken;
  75.         GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

  76.         {
  77.                 char *pCodeStr=argv[1];
  78.                 CQR_Encode* pQR_Encode = new CQR_Encode;

  79.                 //生成QR二维码数据
  80.                 if (! pQR_Encode->EncodeData(QR_LEVEL_H, QR_VRESION_S, TRUE, -1,  pCodeStr))
  81.                 {
  82.                         fprintf(stdout, "Encode data error\n");
  83.                         return 1;
  84.                 }

  85.                 //根据生成的QR二进制数据 建立图片的长宽
  86.                 int qwith=pQR_Encode->m_nSymbleSize*BF_ZOOM+BF_MARGIN*2, qhigh=pQR_Encode->m_nSymbleSize*BF_ZOOM+BF_MARGIN*2;

  87.                 //建立位图文件
  88.                 Rect qrect(0, 0, qwith, qhigh);
  89.                 Bitmap* tbmp=new Bitmap(qwith, qhigh, PixelFormat24bppRGB);
  90.                 BitmapData* pBitmapData = new BitmapData;
  91.                 //并锁定位图二进制信息
  92.                 tbmp->LockBits(&qrect, ImageLockModeRead, PixelFormat24bppRGB, pBitmapData);
  93.                 BYTE *pByte = (BYTE *)pBitmapData->Scan0;
  94.                 int  iOffset = pBitmapData->Stride - qwith*3;

  95.                 //遍历位图每个点
  96.                 for(int i=0; i <qwith; i++)
  97.                 {
  98.                         for(int j=0; j <qhigh; j++)
  99.                         {
  100.                                 //如果位图中的点满足填充白色,则将该点像素值设为RGB(255,255,255)
  101.                                 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])
  102.                                 {
  103.                                         pByte[0] = 255;
  104.                                         pByte[1] = 255;
  105.                                         pByte[2] = 255;
  106.                                 }
  107.                                 pByte+=3;
  108.                         }
  109.                         pByte += iOffset;
  110.                 }
  111.                 //解除锁定
  112.                 tbmp->UnlockBits(pBitmapData);

  113.                 //建立单值位图sbmp,并进行位图拷贝
  114.                 Bitmap* sbmp=tbmp->Clone(qrect, PixelFormat1bppIndexed);

  115.                 //在控WIN制台显示QR图片
  116.                 if(argc==2)
  117.                 {
  118.                         Graphics* graph=new Graphics(GetDesktopWindow());
  119.                         graph->DrawImage(sbmp, qrect);
  120.                         DeleteObject(graph);
  121.                 }
  122.                 else
  123.                 {

  124.                         //对位图sbmp进行编码,并输出为png格式
  125.                         CLSID clsid;
  126.                         if(GetEncoderClsid(L"image/png", &clsid))
  127.                         {
  128.                                 if(sbmp->Save(LW(argv[2]), &clsid, NULL) != S_OK)
  129.                                 {
  130.                                         fprintf(stdout, "Save image failed\n");
  131.                                         return 1;
  132.                                 }
  133.                         }
  134.                         else
  135.                         {
  136.                                 fprintf(stdout, "Encode image failed\n");
  137.                                 return 1;
  138.                         }
  139.                 }

  140.                 //释放内存
  141.                 delete pQR_Encode;
  142.                 delete pBitmapData;
  143.                 delete tbmp;
  144.                 delete sbmp;
  145.         }

  146.         //关闭GDI+
  147.         GdiplusShutdown(gdiplustoken);
  148.         return 0;
  149. }
复制代码
.
.
【Python版】

脚本代码:
  1. #-*- encoding:utf-8 -*-
  2. # Made by Happy

  3. # 导入QR模块
  4. import qrcode
  5. import image
  6. import getopt,sys

  7. def QR_Encode(text):

  8.         qr=qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=10, border=1)
  9.         qr.add_data(text)
  10.         qr.make(fit=True)
  11.         return qr.make_image()

  12. def main():
  13.        
  14.         tv="";ov="";flag=False

  15.         ops,avs = getopt.getopt(sys.argv[1:], "ht:so:r:", ["help", "text", "show", "out", "recognise"])

  16.         if len(sys.argv) == 1:
  17.                 print("Usage: pqr [-t text] [-o outfile] [-s show image]")
  18.                 sys.exit(1)

  19.         for op,av in ops:

  20.                 if op in ("-h", "--help"):
  21.                         print("Usage: pqr [-t text] [-o outfile] [-s show image]")
  22.                         sys.exit(0)

  23.                 elif op in ("-t","--text"):
  24.                         tv=av

  25.                 elif op in ("-o","--out"):
  26.                         ov=av

  27.                 elif op in ("-s","--show"):
  28.                         flag=True

  29.                 else:
  30.                         print("Unrecognise options '%s'" %av)
  31.                         sys.exit(1)

  32.         if not tv in '':
  33.        
  34.                 img=QR_Encode(tv)

  35.                 if not ov in '':
  36.                         img.save(ov)

  37.                 if flag is True:
  38.                         img.show()
  39.         else:
  40.                 print("Please input text string")
  41.                 sys.exit(1)
  42. main()
复制代码
使用方法:

  1. Usage: pqr [-t text] [-o outfile] [-s show image]
  2. Example:
  3.     pqr -t 你好 -o 3.png
复制代码
pqr支持的二维码汉字容量惊人,生成的图片体积极小、清晰度极高、容错识别极强。且pqr.exe比C语言版qr.exe功能多,可直接显示二维码,安装响应模块,可支持多种特殊功能。安装zbar库,还能支持条码识别,py脚本请参看15楼。

评分

参与人数 3技术 +3 收起 理由
codegay + 1 11
老刘1号 + 1 识别率不佳
523066680 + 1 高产量

查看全部评分

发表于 2017-5-11 23:01:20 | 显示全部楼层
3星、QQ表示根本扫不出……
发表于 2017-5-11 23:11:10 | 显示全部楼层
本帖最后由 523066680 于 2017-5-11 23:13 编辑

回复 2# 老刘1号


    魅族,微信扫描很快扫出来。
不过手机内置的二维码扫描器有点难。
发表于 2017-5-11 23:19:43 | 显示全部楼层
回复 3# 523066680


    是啊……
希望作者向nro同志学习下……
这个太难扫了……
 楼主| 发表于 2017-5-11 23:35:15 | 显示全部楼层
回复 3# 523066680
速度快就行,不过我觉得还可以继续优化,但是受控制台限制,样子也只能那样了。
 楼主| 发表于 2017-5-11 23:36:28 | 显示全部楼层
回复 4# 老刘1号
因为是控制台上直接扫嘛,所以应该适应适应,后续将推出三维码,彻底颠覆二维码编码规则。我的编码我做主。
发表于 2017-5-12 10:43:45 | 显示全部楼层
忘记是哪个软件了,特色之一就是能在发生错误的时候,同时显示一个二维码,方便用户去搜索信息以及拿给其它人咨询。
发表于 2017-5-12 10:50:04 | 显示全部楼层
快弄github啊。学一学,用图形界面的软件不难的。
 楼主| 发表于 2017-5-12 11:12:23 | 显示全部楼层
回复 8# codegay
图形就不要了,因为是控制塔程序啊,如何直接显示图片都不属于命令行了,就没法发到第三方里。我这个是纯命令行,字符串二维码,根正苗红。
不过我可以在程序员小工具里,补上个带窗口的版本。
发表于 2017-5-12 11:37:35 | 显示全部楼层
回复 9# happy886rr


    我是说你这么多开源的代码,学学用github。放上面。
 楼主| 发表于 2017-5-12 11:40:12 | 显示全部楼层
回复 10# codegay
我都是用的git的命令行,但是感觉进度条没有,我打算写个git第三方,跟github对接。
发表于 2017-5-12 11:45:04 | 显示全部楼层
回复 11# happy886rr


    6666
发表于 2017-5-13 10:01:24 | 显示全部楼层
放源码放源码
发表于 2017-5-13 13:41:35 | 显示全部楼层
没反色看着不顺眼....
 楼主| 发表于 2017-5-13 13:44:17 | 显示全部楼层
本帖最后由 happy886rr 于 2017-5-14 13:05 编辑

回复 13# codegay
py版发布,安装个zbar库,还能支持条码识别。
使用方法:
  1. Usage: pqr [-t text] [-o outfile] [-s show image]
复制代码
pqr支持的二维码汉字容量惊人,生成的图片体积极小、清晰度极高、容错识别极强。且pqr.exe比C语言版qr.exe功能多,可直接显示二维码,安装响应模块,可支持多种特殊功能。

体积太大,就不上传了,请君编译吧。

评分

参与人数 1PB +6 技术 +1 收起 理由
523066680 + 6 + 1 666

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:24 , Processed in 0.023025 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表