Solved! Go to Solution.
Solved by Lisa_Pohlmeyer. Go to Solution.
I'd think that what you want is not the reverse of Xrefernce Manager, because now you need to find if an image file is referenced in multiple drawings, meaning AutoCAD must open/read all drawings in question (say, all drawing files in a folder) to find out if the image file is referenced in a drawing or not.
So, the first thing you need to do is to write code to identify if a drawing has RasterImageDef/RasterImage that refers to the source file. Then you can process all drawings in a folder, either opening them one by one in AUtoCAD, or reading the drawing files as side database.
Here is some code doing that (not tested).
First, find a list of image file names in a drawing:
using System.Collections.Generic; using Autodesk.AutoCAD.DatabaseServices; namespace IdentifyRasterImageInDwg { public static class RasterImageFinder { public static string[] GetRasterImageNamesInDrawing(Database db) { List<string> names = new List<string>(); using (Transaction tran = db.TransactionManager.StartTransaction()) { //Get ImageDictionary ID ObjectId dictId = RasterImageDef.GetImageDictionary(db); if (!dictId.IsNull) { DBDictionary dict = (DBDictionary) tran.GetObject(dictId, OpenMode.ForRead); foreach (DBDictionaryEntry entry in dict) { RasterImageDef imgDef = (RasterImageDef) tran.GetObject(entry.Value, OpenMode.ForRead); names.Add(imgDef.SourceFileName); } } tran.Commit(); } return names.ToArray(); } } }
Above code only search ImageDictionary in a Database to get image source file name of each RasterImageDef object.
Here is the command class that uses above code. The second command method does what you want:
using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; [assembly: CommandClass(typeof(IdentifyRasterImageInDwg.MyCommands))] namespace IdentifyRasterImageInDwg { public class MyCommands { [CommandMethod("GetImgInDwg")] public static void RunMyCommand() { Document dwg = Application.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; string[] imgNames = RasterImageFinder.GetRasterImageNamesInDrawing(dwg.Database); if (imgNames.Length > 0) { foreach (var name in imgNames) { string fileName = System.IO.Path.GetFileName(name); string filePath = System.IO.Path.GetDirectoryName(name); ed.WriteMessage("\nImage name: {0}", fileName); } } else { ed.WriteMessage("\nNo image is inserted in current drawing."); } Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt(); } [CommandMethod("SearchDwgForImg")] public static void SearchRasterImagesInDrawings() { Document dwg = Application.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; string imageFileName = "MyImage.png"; string folderName = "C:\\Temp"; List<string> dwgs = new List<string>(); string[] dwgFiles = System.IO.Directory.GetFiles(folderName, "*.dwg"); foreach (var dwgFile in dwgFiles) { ed.WriteMessage("\nSearch drawing {0}...", System.IO.Path.GetFileName(dwgFile)); using (Database db = new Database(false, true)) { db.ReadDwgFile( dwgFile, System.IO.FileShare.Read, false, null); string[] imgNames = RasterImageFinder.GetRasterImageNamesInDrawing(db); foreach (var name in imgNames) { string img = System.IO.Path.GetFileName(name); if (img.ToUpper() == imageFileName.ToUpper()) { dwgs.Add(dwgFile); break; } } } } ed.WriteMessage("\n{0} drawing file{1} searched.", dwgFiles.Length, dwgFiles.Length > 0 ? "s" : ""); if (dwgs.Count > 0) { ed.WriteMessage("\n{0} ha{1} reference to image file {2}:", dwgs.Count, dwgs.Count>1?"ve":"s",imageFileName); foreach (var d in dwgs) { ed.WriteMessage("\n{0}", d); } } else { ed.WriteMessage("\nNo drawing file has reference to {0}.", imageFileName); } Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt(); } } }
Well, if you need to search quite some drawings, you may want to use some kind of visual progress indicator to let user know AutoCAD is busy working.
HTH
Norman Yuan