一个用包围盒转化cad为png格式的方法
namespace DWGScreenshot{
public class Commands
{
/// <summary>
/// 截图指定的 DWG 文件(不打开文件,直接读取包围盒)
/// 使用方法:在 CAD 命令行输入 DWGSHOT
/// </summary>
public void ScreenshotDWG()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// 1. 获取 DWG 文件路径
PromptStringOptions pso = new PromptStringOptions("\n输入 DWG 文件路径: ");
pso.AllowSpaces = true;
PromptResult pr = ed.GetString(pso);
if (pr.Status != PromptStatus.OK)
return;
string dwgPath = pr.StringResult.Trim('"');
if (!File.Exists(dwgPath))
{
ed.WriteMessage($"\n文件不存在: {dwgPath}");
return;
}
try
{
// 2. 读取 DWG 文件并计算包围盒(不打开文件)
Extents3d? bounds = GetDWGBounds(dwgPath);
if (!bounds.HasValue)
{
ed.WriteMessage($"\n无法获取文件包围盒: {dwgPath}");
return;
}
// 3. 扩大包围盒 5mm
double expansion = 5.0; // 5mm
Point3d minPoint = new Point3d(
bounds.Value.MinPoint.X - expansion,
bounds.Value.MinPoint.Y - expansion,
bounds.Value.MinPoint.Z
);
Point3d maxPoint = new Point3d(
bounds.Value.MaxPoint.X + expansion,
bounds.Value.MaxPoint.Y + expansion,
bounds.Value.MaxPoint.Z
);
ed.WriteMessage($"\n原始包围盒: ({bounds.Value.MinPoint.X:F2}, {bounds.Value.MinPoint.Y:F2}) - ({bounds.Value.MaxPoint.X:F2}, {bounds.Value.MaxPoint.Y:F2})");
ed.WriteMessage($"\n扩大后包围盒: ({minPoint.X:F2}, {minPoint.Y:F2}) - ({maxPoint.X:F2}, {maxPoint.Y:F2})");
// 4. 先打开文件
Application.DocumentManager.Open(dwgPath, false);
Document newDoc = Application.DocumentManager.MdiActiveDocument;
// 5. 缩放到扩大后的包围盒
Point3d P1 = new Point3d(
bounds.Value.MinPoint.X,
bounds.Value.MinPoint.Y,
bounds.Value.MinPoint.Z
);
Point3d P2 = new Point3d(
bounds.Value.MaxPoint.X,
bounds.Value.MaxPoint.Y,
bounds.Value.MaxPoint.Z
);
var line = new Line(minPoint, maxPoint);
Env.Editor.ZoomObject(line, 50);
System.Threading.Thread.Sleep(500); // 500毫秒延迟
// 6. 输出 PNG - 使用 Editor.Command 同步执行
string outputPath = Path.ChangeExtension(dwgPath, ".png");
// 方法1:使用 Editor.Command 同步执行(推荐)
newDoc.Editor.Command("PNGOUT", outputPath, "ALL", "");
// 或者方法2:使用 acedCmd(需要 P/Invoke)
// string pngCommand = $"PNGOUT\n\"{outputPath}\"\nALL\n\n";
// newDoc.SendStringToExecute(pngCommand, false, false, false);
// System.Threading.Thread.Sleep(2000); // 等待2秒
// 或者方法3:直接选择所有对象后执行
// newDoc.Editor.Command("_SELECT", "ALL", "");
// SelectionSet ss = newDoc.Editor.SelectAll().Value;
// newDoc.Editor.Command("PNGOUT", outputPath, ss, "");
ed.WriteMessage($"\n截图已保存到: {outputPath}");
}
catch (Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
}
}
/// <summary>
/// 获取 DWG 文件的包围盒(不打开文件)
/// </summary>
private Extents3d? GetDWGBounds(string dwgPath)
{
Extents3d? result = null;
// 创建临时数据库读取 DWG
using (Database sourceDb = new Database(false, true))
{
try
{
// 读取 DWG 文件
sourceDb.ReadDwgFile(dwgPath, FileOpenMode.OpenForReadAndAllShare, true, "");
using (Transaction trans = sourceDb.TransactionManager.StartTransaction())
{
// 获取模型空间
BlockTable bt = trans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord ms = trans.GetObject(bt, OpenMode.ForRead) as BlockTableRecord;
// 计算所有实体的包围盒
foreach (ObjectId id in ms)
{
Entity entity = trans.GetObject(id, OpenMode.ForRead) as Entity;
if (entity != null && entity.Visible)
{
try
{
Extents3d entityExtents = entity.GeometricExtents;
if (!result.HasValue)
{
result = entityExtents;
}
else
{
// 合并包围盒
result = new Extents3d(
new Point3d(
Math.Min(result.Value.MinPoint.X, entityExtents.MinPoint.X),
Math.Min(result.Value.MinPoint.Y, entityExtents.MinPoint.Y),
Math.Min(result.Value.MinPoint.Z, entityExtents.MinPoint.Z)
),
new Point3d(
Math.Max(result.Value.MaxPoint.X, entityExtents.MaxPoint.X),
Math.Max(result.Value.MaxPoint.Y, entityExtents.MaxPoint.Y),
Math.Max(result.Value.MaxPoint.Z, entityExtents.MaxPoint.Z)
)
);
}
}
catch
{
// 忽略没有几何范围的实体
}
}
}
trans.Commit();
}
}
catch
{
return null;
}
}
return result;
}
}
}
感谢楼主分享!!
页:
[1]