来自edata的聊天记录节选,嘻嘻..
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 { get; set; }
public List<BitArray> ModuleMatrix { get; set; }
string _Content;
int _Version;
/// <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;
}
public Color QRBitmapColor1 { get; set; } = Color.Black;
public Color QRBitmapColor2 { get; set; } = Color.White;
public Image QRBitmap { get; set; }
/// <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);
}
static Dictionary<string, ImageFormat> ExtDict;
/// <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)
{
var name = item.Name.ToLower();
if (!ExtDict.ContainsKey(name))
{
try
{
//类型强转可能报错
var a = (ImageFormat)item.GetValue(imgf, null);//获取属性的值
ExtDict.Add(name, a);
}
catch
{ }
}
}
}
if (ExtDict.ContainsKey(ext))
QRBitmap.Save(imgPath, ExtDict[ext]);
}
}
}
命令
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using DoubleCollection = Autodesk.AutoCAD.Geometry.DoubleCollection;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
using Color = Autodesk.AutoCAD.Colors.Color;
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 => {
var btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
CreateQRCodeHatch(tr, btr, bits, false);//不需要背景
btr.Dispose();
});
}
/// <summary>
/// 创建二维码填充
/// </summary>
/// <param name="tr"></param>
/// <param name="btr"></param>
/// <param name="bits">二维码矩阵</param>
/// <param name="needBackground">是否需要背景</param>
void CreateQRCodeHatch(Transaction tr, BlockTableRecord btr, IEnumerable<BitArray> bits, bool needBackground = true)
{
Hatch hatchBackground = null;
if (needBackground)
{
//填充背景_白色
hatchBackground = CreateHatch("Solid", Color.FromRgb(255, 255, 255));
btr.AppendEntity(hatchBackground);
tr.AddNewlyCreatedDBObject(hatchBackground, true);
}
//填充前景_其他颜色
var hatch2Color = Color.FromRgb(160, 200, 58);//绿色
hatch2Color = Color.FromRgb(1, 1, 1); //黑色
var hatch = CreateHatch("Solid", hatch2Color);
hatch.ColorIndex = 2; //黄色
btr.AppendEntity(hatch);
tr.AddNewlyCreatedDBObject(hatch, true);
ChangeHatch(tr, bits, hatch, hatchBackground);
//重新计算填充
if (hatchBackground == null)
hatchBackground.EvaluateHatch(true);
hatch.EvaluateHatch(true);
}
/// <summary>
/// 创建填充
/// </summary>
Hatch CreateHatch(string hatchName, Color hatchColor)
{
var hat = new Hatch();
hat.SetDatabaseDefaults();
hat.SetHatchPattern(HatchPatternType.PreDefined, hatchName);
hat.Color = hatchColor;
return hat;
}
/// <summary>
/// 修改填充
/// </summary>
void ChangeHatch(Transaction tr, IEnumerable<BitArray> bits, Hatch hatch, Hatch hatchBackground = null, int size = 100)
{
//设置多段线的凸度,数量和点集一样,而且自动赋值0
var bluges = new DoubleCollection(new double[5]);
int i = 0;
foreach (var bitArray in bits)
{
for (int j = 0; j < bitArray.Length; j++)
{
//创建矩形框5个点,否则填充是不闭合的
var p1 = new Point2d(j * size, i * 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, p1 };
if (bitArray.Get(j))
hatch.AppendLoop(HatchLoopTypes.Default, pts, bluges, tr);//填充黑块
else
if (hatchBackground != null)
hatchBackground.AppendLoop(HatchLoopTypes.Default, pts, bluges, tr);//填充白色背景
}
i--; //换行
}
}
}
}
仿高版本的填充函数
public static partial class EntityAdd
{
/// <summary>
/// 仿高版本的填充函数
/// </summary>
/// <param name="hatch"></param>
/// <param name="hatchLoopTypes"></param>
/// <param name="pts"></param>
/// <param name="bluges"></param>
public static void AppendLoop(this Hatch hatch,
HatchLoopTypes hatchLoopTypes, Point2dCollection pts, DoubleCollection bluges,
Transaction tr, bool removePline = true)
{
#if NET35 //留个作业🤣
var bvws = new List<BulgeVertexWidth>();
var itor1 = pts.GetEnumerator();
var itor2 = bluges.GetEnumerator();
while (itor1.MoveNext() && itor2.MoveNext())
bvws.Add(new BulgeVertexWidth(itor1.Current, itor2.Current));
var pl = EntityAdd.AddPolyLineToEntity(bvws);
var id = EntityAdd.AddEntityToMsPs(tr, hatch.Database, pl);//因为这里没有事务
hatch.AppendLoop(hatchLoopTypes, new ObjectIdCollection() { id });
if (removePline)
tr.EntityErase(new List<ObjectId>() { id });
#else
//2011新增API
hatch.AppendLoop(hatchLoopTypes, pts, bluges);
#endif
}
相关引用
db.Action(tr=> 本博客参考:cad.net 委托的学习 无返回值写法
BulgeVertexWidth 本博客参考
效果
控制台
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");
}
}
}
(完)