來自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");
}
}
}
(完)