如何使用 .Net 在 autocad 中删除 RasterImage?

How to delete a RasterImage in autocad using .Net?

我在 dwg 中附加了一个光栅图像 jpg 作为外部参照,我想分离该文件。我怎样才能删除它?

我不认为它一定是外部参照有什么特别之处。我从标题为“Detaching an AutoCAD external reference using .NET”的文章中获取了下面的代码。

来自描述

There’s nothing very surprising about the code, although it does show how to loop selection based on a core property of the selected object (or even one connected to it, as is the case, here), rather than just trusting AutoCAD to do so based on the object’s type. We also have to pass the ObjectId of the defining BlockTableRecord to the Database.DetachXref() method, which is certainly worth being aware of.

代码:

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

namespace XrefApplication
{
  public class Commands
  {
    [CommandMethod("DX")]
    static public void DetachXref()
    {
      Document doc =
        Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;

      // Select an external reference

      Transaction tr =
        db.TransactionManager.StartTransaction();
      using (tr)
      {
        BlockTableRecord btr = null;
        ObjectId xrefId = ObjectId.Null;

        // We'll loop, as we need to open the block and
        // underlying definition to check the block is
        // an external reference during selection

        do
        {
          PromptEntityOptions peo =
            new PromptEntityOptions(
              "\nSelect an external reference:"
            );
          peo.SetRejectMessage("\nMust be a block reference.");
          peo.AddAllowedClass(typeof(BlockReference), true);

          PromptEntityResult per = ed.GetEntity(peo);
          if (per.Status != PromptStatus.OK)
            return;

          // Open the block reference

          BlockReference br =
            (BlockReference)tr.GetObject(
              per.ObjectId,
              OpenMode.ForRead
            );

          // And the underlying block table record

          btr =
            (BlockTableRecord)tr.GetObject(
              br.BlockTableRecord,
              OpenMode.ForRead
            );

          // If it's an xref, store its ObjectId

          if (btr.IsFromExternalReference)
          {
            xrefId = br.BlockTableRecord;
          }
          else
          {
            // Otherwise print a message and loop

            ed.WriteMessage(
              "\nMust be an external reference."
            );
          }
        }
        while (!btr.IsFromExternalReference);

        // If we have a valid ObjectID for the xref, detach it

        if (xrefId != ObjectId.Null)
        {
          db.DetachXref(xrefId);
          ed.WriteMessage("\nExternal reference detached.");
        }

        // We commit the transaction simply for performance
        // reasons, as the detach is independent

        tr.Commit();
      }
    }
  }
}

MyCadSite.com you can read more about Xrefs outside of the C# API. In the interface, it all appears to attach the same way. When looking at this code on Typepad 可以看出,数据库中的引用也都以相同的方式处理。

来自作者:

The db.GetHostDwgXrefGraph() method returns the Xref hierarchy for the current drawing as an XrefGraph object. Here’s a simple code snippet to demonstrate its use – in this case to print the Xref structure of the current drawing to the command line.

代码:

[CommandMethod("XrefGraph")]
public static void XrefGraph()
{
  Document doc = Application.DocumentManager.MdiActiveDocument;
  Database db = doc.Database;
  Editor ed = doc.Editor;
  using (Transaction Tx = db.TransactionManager.StartTransaction())
  {
    ed.WriteMessage("\n---Resolving the XRefs------------------");
    db.ResolveXrefs(true, false);
    XrefGraph xg = db.GetHostDwgXrefGraph(true);
    ed.WriteMessage("\n---XRef's Graph-------------------------");
    ed.WriteMessage("\nCURRENT DRAWING");
    GraphNode root = xg.RootNode;
    printChildren(root, "|-------", ed, Tx);
    ed.WriteMessage("\n----------------------------------------\n");
  }
}

// Recursively prints out information about the XRef's hierarchy
private static void printChildren(GraphNode i_root, string i_indent,
                                  Editor i_ed, Transaction i_Tx)
{
  for (int o = 0; o < i_root.NumOut; o++)
  {
    XrefGraphNode child = i_root.Out(o) as XrefGraphNode;
    if (child.XrefStatus == XrefStatus.Resolved)
    {
      BlockTableRecord bl =
        i_Tx.GetObject(child.BlockTableRecordId, OpenMode.ForRead)
            as BlockTableRecord;
      i_ed.WriteMessage("\n" + i_indent + child.Database.Filename);
      // Name of the Xref (found name)
      // You can find the original path too:
      //if (bl.IsFromExternalReference == true)
      // i_ed.WriteMessage("\n" + i_indent + "Xref path name: "
      //                      + bl.PathName);
      printChildren(child, "| " + i_indent, i_ed, i_Tx);
    }
  }
}

我找到了另一个解决问题的方法:

 private void DetachRasterImage(Transaction transaction, Database database, List<string> jpgPaths)
    {
        Dictionary<ObjectId, RasterImageDef> imageDefinitions = new Dictionary<ObjectId, RasterImageDef>();
        DBDictionary imageDictionary = (DBDictionary)transaction.GetObject(RasterImageDef.GetImageDictionary(database), OpenMode.ForWrite);
        foreach (DBDictionaryEntry entry in imageDictionary)
        {
            ObjectId id = (ObjectId)entry.Value;
            RasterImageDef rasterImageDef = transaction.GetObject(id, OpenMode.ForWrite) as RasterImageDef;
            if (jpgPaths.Contains(rasterImageDef.LocateActivePath()))
                imageDefinitions.Add(id, rasterImageDef);
        }
        foreach (KeyValuePair<ObjectId, RasterImageDef> item in imageDefinitions)
        {
            imageDictionary.Remove(item.Key);
            item.Value.Erase();
        }           
    }