.NET

Reply
*Expert Elite*
LisaPohlmeyer
Posts: 595
Registered: ‎01-14-2009
Message 1 of 3 (244 Views)
Accepted Solution

Locating all jpg references

244 Views, 2 Replies
12-31-2013 05:38 AM
I searched the groups and the closest discussion I could find was here but there didn't seem to be a clear cut solution. http://forums.autodesk.com/t5/NET/How-to-programmatically-find-all-references-xref-dwg-jpg-pdf-OLE/m... I have a jpg file that I needed to apply some transparency to and saved it as a png file. I now want to delete the jpg file from the folder but it's being referenced in several drawings, and I don't know which ones. Is there a way to reverse the function of Reference Manager (perhaps with a different app), ie find all the drawing files that reference my jpg file?
Lisa Pohlmeyer

C3D 2012 SP4, C3D 2015
Please use "Accept as Solution" if this solved your issue.
*Expert Elite*
norman.yuan
Posts: 1,045
Registered: ‎04-27-2009
Message 2 of 3 (220 Views)

Re: Locating all jpg references

12-31-2013 10:44 PM in reply to: LisaPohlmeyer

 

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

 

*Expert Elite*
LisaPohlmeyer
Posts: 595
Registered: ‎01-14-2009
Message 3 of 3 (186 Views)

Re: Locating all jpg references

01-02-2014 06:37 AM in reply to: norman.yuan
The solution that worked for me is here: http://forums.autodesk.com/t5/AutoCAD-2010-2011-2012-DWG/Finding-all-jpg-references-in-drawings/m-p/...
Lisa Pohlmeyer

C3D 2012 SP4, C3D 2015
Please use "Accept as Solution" if this solved your issue.
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!