cad.net 生成二维码
生成二维码模式1:cad图元
来自edata的聊天记录节选,嘻嘻..
调用命令
#if !HC2020
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;
#else
using GrxCAD.EditorInput;
using GrxCAD.Geometry;
using GrxCAD.Runtime;
using Acap = GrxCAD.ApplicationServices.Application;
using GrxCAD.DatabaseServices;
using GrxCAD.Colors;
#endif
using System.Collections.Generic;
using System.Collections;
namespace JoinBox
{
public class CmdTest_QRCodeGeneratorClass
{
[CommandMethod("CmdTest_QRCodeGenerator")]
public void CmdTest_QRCodeGenerator()
{
var msg = "二维码测试";
//msg = "https://www.cnblogs.com/JJBox";
msg = "https://www.cnblogs.com/JJBox/p/14485956.html";
var qr = new QRCodeEncoder(msg);
qr.Build();
var bits = qr.ModuleMatrix;
//这里是新建图片到桌面上
//qr.BuildBitmap();
//var desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
//qr.SaveBitmap(desktop + @"\QRCode.jpg");
//这里新建图元到cad数据库
var dm = Acap.DocumentManager;
var doc = dm.MdiActiveDocument;
var db = doc.Database;
db.Action(tr => {
CreateQRCodeHatch(tr, db, bits);//不需要背景
});
}
/// <summary>
/// 创建二维码填充
/// </summary>
/// <param name="tr"></param>
/// <param name="db"></param>
/// <param name="bits">二维码矩阵</param>
/// <param name="needBackground">是否需要背景</param>
void CreateQRCodeHatch(Transaction tr, Database db,
IEnumerable<BitArray> bits,
bool needBackground = true)
{
var hatchName = "Solid";
HatchInfo hatchBackground = null;
if (needBackground)
{
//填充背景_白色
var hatchColor = Color.FromRgb(255, 255, 255);
hatchBackground = new HatchInfo(false)
.Mode1PreDefined(hatchName)
.Action(ent => ent.Color = hatchColor);
}
//填充前景_其他颜色
var hatch2Color = Color.FromRgb(160, 200, 58);//绿色
hatch2Color = Color.FromRgb(1, 1, 1); //黑色
var hatch = new HatchInfo(false)
.Mode1PreDefined(hatchName)
.Action(ent => ent.Color = hatch2Color);
TimeHelper.RunTime(() => {
ChangeHatch(tr, db, bits, hatch, hatchBackground);
}, "ChangeHatch");
TimeHelper.RunTime(() => {
hatch.Build(tr, db);
}, "A");
TimeHelper.RunTime(() => {
hatchBackground?.Build(tr, db);
}, "B");
//删除生成的边界
hatch.EraseBoundary(tr);
hatchBackground?.EraseBoundary(tr);
}
/// <summary>
/// 修改填充
/// </summary>
void ChangeHatch(Transaction tr, Database db,
IEnumerable<BitArray> bits,
HatchInfo hatch,
HatchInfo hatchBackground = null,
int size = 100)
{
//设置多段线的凸度,数量和点集一样,而且自动赋值0
var bluges = new DoubleCollection(new double[5]);
int row = 0;
foreach (var bitArray in bits)
{
for (int column = 0; column < bitArray.Length; column++)
{
//创建矩形框5个点,否则填充是不闭合的
var p1 = new Point2d(column * size, row * size);
var p2 = new Point2d(p1.X + size, p1.Y);
var p3 = new Point2d(p2.X, p1.Y + size);
var p4 = new Point2d(p1.X, p3.Y);
var pts = new Point2dCollection { p1, p2, p3, p4 };
if (bitArray.Get(column))
{
//前景黑块
hatch.AppendLoop(pts, bluges, tr, db);
}
else
{
//背景白色
hatchBackground?.AppendLoop(pts, bluges, tr, db);
}
pts.Dispose();
}
row--; //换行
}
}
}
}
封装QRCoder
using System.Drawing;
using System.Collections.Generic;
using System.Collections;
using System;
using System.IO;
using System.Drawing.Imaging;
using QRCoder;//引入nuget包:QRCoder
namespace JoinBox
{
public class QRCodeEncoder
{
public QRCode? QRCode;
public List<BitArray>? ModuleMatrix;
string _Content;
int _Version;
public Color QRBitmapColor1 = Color.Black;
public Color QRBitmapColor2 = Color.White;
public Image? QRBitmap;
static Dictionary<string, ImageFormat>? ExtDict;
/// <summary>
/// 创建二维码
/// </summary>
/// <param name="codeContent">信息</param>
/// <param name="version">版本1~40,如果是0会依照内容缩放图片</param>
/// <returns></returns>
public QRCodeEncoder(string codeContent, int version = 10)
{
_Content = codeContent;
//当参数一是: https://www.cnblogs.com/JJBox/p/14485956.html
//测试手机QQ,参数2为5以下不能识别.
//如果参数1内容多的话,参数2偏大则更容易识别.
//(是否设置为一个比例而不是一个固定版本?)
_Version = version;
}
/// <summary>
/// 构建
/// </summary>
public void Build()
{
var generator = new QRCodeGenerator();
var data = generator.CreateQrCode(
_Content,
QRCodeGenerator.ECCLevel.H,//这里设置容错率的一个级别
false, //手机QQ能不能扫描就看这里了
false, //手机QQ能不能扫描就看这里了
QRCodeGenerator.EciMode.Utf8,
_Version);
QRCode = new QRCode(data);
ModuleMatrix = data.ModuleMatrix;
}
/// <summary>
/// 构建位图
/// </summary>
/// <param name="pixel">像素点大小</param>
/// <param name="size">图标尺寸</param>
/// <param name="border">图标边框厚度</param>
/// <param name="whiteEdge">二维码白边</param>
/// <returns></returns>
public void BuildBitmap(int pixel = 5, int size = 5, int border = 0, bool whiteEdge = false)
{
if (QRCode == null)
throw new ArgumentNullException(nameof(QRCode));
QRBitmap = QRCode.GetGraphic(pixel,
QRBitmapColor1,
QRBitmapColor2,
null,
size,
border,
whiteEdge);
}
/// <summary>
/// 保存位图
/// </summary>
/// <param name="imgPath">带文件名后缀的完整路径</param>
/// <returns></returns>
public void SaveBitmap(string imgPath)
{
if (QRBitmap == null)
throw new ArgumentNullException(nameof(QRBitmap));
//反射ImageFormat获取匹配后缀类型
if (!Path.HasExtension(imgPath))
throw new ArgumentNullException("路径没有后缀");
var ext = Path.GetExtension(imgPath).ToLower();
ext = ext.Replace(".", string.Empty).Replace("jpg", "jpeg");
if (ExtDict == null)//仅运行程序的第一次执行
{
ExtDict = new();
var imgf = typeof(ImageFormat);
var properties = imgf.GetProperties();
foreach (var item in properties)
{
if (item == null)
continue;
var name = item.Name.ToLower();
if (!name.Contains("guid") && !ExtDict.ContainsKey(name))
{
var imageFormat = item.GetValue(imgf, null) as ImageFormat;
if (imageFormat != null)
ExtDict.Add(name, imageFormat);
}
}
}
if (ExtDict.ContainsKey(ext))
QRBitmap.Save(imgPath, ExtDict[ext]);
}
}
}
相关引用
db.Action 本博客参考:cad.net 委托的学习 无返回值写法
效果
生成二维码模式2:控制台生成图片
class Program
{
static void Main(string[] args)
{
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
var msg = "https://www.cnblogs.com/JJBox";
{
var qr = new QRCodeEncoder(msg);
qr.Build();
qr.BuildBitmap();
qr.SaveBitmap(desktop + @"\QRCode.jpg");
}
msg = "https://www.cnblogs.com/JJBox/p/14485956.html";
{
var qr = new QRCodeEncoder(msg);
qr.Build();
qr.BuildBitmap();
qr.SaveBitmap(desktop + @"\QRCode2.jpg");
}
}
}
(完)