明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1487|回复: 4

[其它] 圖中生成二維碼

[复制链接]
发表于 2025-7-9 17:45:16 | 显示全部楼层 |阅读模式
本帖最后由 箭头_Row 于 2025-7-10 00:30 编辑

最初看到Gile的開源庫:關於圖中生成二維碼的程序

具體做了如下優化:
一、下載后發現其引用的QRCoder庫是離線庫,故優化項目文件:InsertQRCodeBlock.csproj

二、取消項目:AutoCADQRCoder,合併至:InsertQRCodeBlock。

三、漢化了對話框。

生成圖形如圖,另源碼是用WINFORM寫的界面,需優化參數設置,因其沒有做到保存上一次的參數設置。


詳見代碼:
優化后庫:AutocadQRCoder: All the magic of AutocadQRCoder comes from the basic use of QRCoder library to create AutoCAD entities (block or hatch) featuring QR Codes.

Gile的開源庫:gileCAD/AutocadQRCoder: QRCoder for AutoCAD



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复

使用道具 举报

发表于 2025-7-9 19:40:21 | 显示全部楼层
为什么不是用我博客,
而且.csproj应该叫项目文件,
所谓的头文件是函数声明,是C/C++才有...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-10 00:24:07 | 显示全部楼层
本帖最后由 箭头_Row 于 2025-7-10 00:29 编辑

優化了下語法,計時器改名了,博客上可以指定大小新建二維碼:

  1. namespace JoinBox
  2. {
  3.     public class CmdTestQrCodeGeneratorClass
  4.     {
  5.         [CommandMethod(nameof(CmdTest_QRCodeGenerator))]
  6.         public void CmdTest_QRCodeGenerator()
  7.         {
  8.             // var msg = "二维码测试";
  9.             var msg = "https://www.cnblogs.com/JJBox";
  10.             // msg = "https://www.cnblogs.com/JJBox/p/14485956.html";
  11.             QrCodeEncoder qr = new(msg);
  12.             qr.Build();
  13.             var bits = qr.ModuleMatrix;

  14.             //这里是新建图片到桌面上
  15.             qr.BuildBitmap();
  16.             var desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
  17.             var file = Path.Combine(desktop, "QRCode.png");
  18.             qr.SaveBitmap(file);

  19.             if (bits is null)
  20.                 return;
  21.             using DBTrans tr = new();
  22.             CreateQrCodeHatch(tr, bits, size: 50); //不需要背景
  23.         }

  24.         /// <summary>
  25.         /// 创建二维码填充
  26.         /// </summary>
  27.         /// <param name="tr"></param>
  28.         /// <param name="bits">二维码矩阵</param>
  29.         /// <param name="needBackground">是否需要背景</param>
  30.         /// <param name="size">尺寸</param>
  31.         private static void CreateQrCodeHatch(
  32.             DBTrans tr,
  33.             IEnumerable<BitArray> bits,
  34.             bool needBackground = true,
  35.             int size = 100
  36.         )
  37.         {
  38.             const string hatchName = "Solid";

  39.             HatchInfo? hatchBackground = null;
  40.             if (needBackground)
  41.             {
  42.                 var hatchColor = Color.FromRgb(255, 255, 255); //填充背景_白色
  43.                 //var hatchColor = Color.FromRgb(255, 0, 0); //填充背景_红色
  44.                 hatchBackground = new HatchInfo(false).Mode1PreDefined(hatchName).Action(ent => ent.Color = hatchColor);
  45.             }
  46.             //填充前景_其他颜色
  47.             // Color hatch2Color = Color.FromRgb(160, 200, 58); //绿色
  48.             Color hatch2Color = Color.FromRgb(1, 1, 1); //黑色

  49.             var hatch = new HatchInfo(false).Mode1PreDefined(hatchName).Action(ent => ent.Color = hatch2Color);
  50.             ChangeHatch(bits, hatch, hatchBackground, size);
  51.             hatch.Build(tr.CurrentSpace);
  52.             hatchBackground?.Build(tr.CurrentSpace);

  53.             //删除生成的边界
  54.             hatch.EraseBoundary();
  55.             hatchBackground?.EraseBoundary();
  56.         }

  57.         /// <summary>
  58.         /// 修改填充
  59.         /// </summary>
  60.         private static void ChangeHatch(
  61.             IEnumerable<BitArray> bits,
  62.             HatchInfo hatch,
  63.             HatchInfo? hatchBackground,
  64.             int size = 100
  65.         )
  66.         {
  67.             DBTrans tr = DBTrans.Top;
  68.             //设置多段线的凸度,数量和点集一样,而且自动赋值0
  69.             var bulges = new DoubleCollection(new double[5]);
  70.             int row = 0;
  71.             foreach (var bitArray in bits)
  72.             {
  73.                 for (int column = 0; column < bitArray.Length; column++)
  74.                 {
  75.                     //创建矩形框5个点,否则填充是不闭合的
  76.                     var p1 = new Point2d(column * size, row * size);
  77.                     var p2 = new Point2d(p1.X + size, p1.Y);
  78.                     var p3 = new Point2d(p2.X, p1.Y + size);
  79.                     var p4 = new Point2d(p1.X, p3.Y);
  80.                     Point2dCollection pts = [p1, p2, p3, p4];

  81.                     if (bitArray.Get(column))
  82.                         hatch.AppendLoop(pts, bulges, tr.CurrentSpace); //前景黑块
  83.                     else
  84.                         hatchBackground?.AppendLoop(pts, bulges, tr.CurrentSpace); //背景白色
  85.                 }
  86.                 row--; //换行
  87.             }
  88.         }
  89.     }
  90. }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-10 00:25:40 | 显示全部楼层
  1. using System.Drawing.Imaging;
  2. using QRCoder;
  3. using Image = System.Drawing.Image;

  4. namespace JoinBox
  5. {
  6.     public class QrCodeEncoder
  7.     {
  8.         public QRCode? QrCode;
  9.         public List<BitArray>? ModuleMatrix;
  10.         private readonly string _content;
  11.         private readonly int _version;

  12.         private readonly System.Drawing.Color _qrBitmapColor1 = System.Drawing.Color.Black;
  13.         private readonly System.Drawing.Color _qrBitmapColor2 = System.Drawing.Color.White;
  14.         public Image? QrBitmap;

  15.         private static Dictionary<string, ImageFormat>? _extDict;

  16.         /// <summary>
  17.         /// 创建二维码
  18.         /// </summary>
  19.         /// <param name="codeContent">信息</param>
  20.         /// <param name="version">版本1~40,如果是0会依照内容缩放图片</param>
  21.         /// <returns></returns>
  22.         public QrCodeEncoder(string codeContent, int version = 10)
  23.         {
  24.             _content = codeContent;

  25.             //当参数一是:  https://www.cnblogs.com/JJBox/p/14485956.html
  26.             //测试手机QQ,参数2为5以下不能识别.
  27.             //如果参数1内容多的话,参数2偏大则更容易识别.
  28.             //(是否设置为一个比例而不是一个固定版本?)
  29.             _version = version;
  30.         }

  31.         /// <summary>
  32.         /// 构建
  33.         /// </summary>
  34.         public void Build()
  35.         {
  36.             var generator = new QRCodeGenerator();
  37.             var data = generator.CreateQrCode(
  38.                 _content,
  39.                 QRCodeGenerator.ECCLevel.H, //这里设置容错率的一个级别
  40.                 false, //手机QQ能不能扫描就看这里了
  41.                 false, //手机QQ能不能扫描就看这里了
  42.                 QRCodeGenerator.EciMode.Utf8,
  43.                 _version
  44.             );
  45.             QrCode = new QRCode(data);
  46.             ModuleMatrix = data.ModuleMatrix;
  47.         }

  48.         /// <summary>
  49.         /// 构建位图
  50.         /// </summary>
  51.         /// <param name="pixel">像素点大小</param>
  52.         /// <param name="size">图标尺寸</param>
  53.         /// <param name="border">图标边框厚度</param>
  54.         /// <param name="whiteEdge">二维码白边</param>
  55.         /// <returns></returns>
  56.         public void BuildBitmap(int pixel = 5, int size = 5, int border = 0, bool whiteEdge = false)
  57.         {
  58.             if (QrCode == null)
  59.                 throw new ArgumentNullException(nameof(QrCode));

  60.             QrBitmap = QrCode.GetGraphic(pixel, _qrBitmapColor1, _qrBitmapColor2, null, size, border, whiteEdge);
  61.         }

  62.         /// <summary>
  63.         /// 保存位图
  64.         /// </summary>
  65.         /// <param name="imgPath">带文件名后缀的完整路径</param>
  66.         /// <returns></returns>
  67.         public void SaveBitmap(string imgPath)
  68.         {
  69.             if (QrBitmap is null)
  70.                 throw new ArgumentNullException(nameof(QrBitmap));

  71.             //反射ImageFormat获取匹配后缀类型
  72.             if (!Path.HasExtension(imgPath))
  73.                 throw new ArgumentNullException($"路径没有后缀");

  74.             var ext = Path.GetExtension(imgPath).ToLower();
  75.             ext = ext.Replace(".", string.Empty).Replace("jpg", "jpeg");

  76.             if (_extDict == null) //仅运行程序的第一次执行
  77.             {
  78.                 _extDict = new Dictionary<string, ImageFormat>();
  79.                 var image = typeof(ImageFormat);
  80.                 var properties = image.GetProperties();
  81.                 foreach (var item in properties)
  82.                 {
  83.                     var name = item.Name.ToLower();
  84.                     if (name.Contains("guid") || _extDict.ContainsKey(name))
  85.                         continue;
  86.                     if (item.GetValue(image, null) is ImageFormat imageFormat)
  87.                         _extDict.Add(name, imageFormat);
  88.                 }
  89.             }

  90.             if (_extDict.TryGetValue(ext, out var value))
  91.                 QrBitmap.Save(imgPath, value);
  92.         }
  93.     }
  94. }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-11 18:28:25 | 显示全部楼层
  1.    int byteCount = Encoding.UTF8.GetByteCount(TextInputBox.Text);
  2.         if (byteCount > 119)
  3.         {
  4.             Acaop.ShowAlertDialog($"当前字节数{byteCount},\n字节数超过了119个!");
  5.             return;
  6.         }


參數設置為10,只支持119個字節。
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-11-16 04:06 , Processed in 0.143082 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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