Lisp to change path of certain images

Lisp to change path of certain images

h_s_walker
Mentor Mentor
1,651 Views
31 Replies
Message 1 of 32

Lisp to change path of certain images

h_s_walker
Mentor
Mentor

Ok long explanation time

Our template has 3 images in there, call them

image1, image 2 and image3.

These images are saved on our server in Z:\....\Projects\Template

Now when we save a drawing  we save it in Z:\....\Projects\Job Number Job Name\Dwgs

In that directory we also have a duplicate of image1, image2 and image3.

Is there any way of changing the path of these three images (one time only) when the drawing is first saved from "Z:\....\Projects\Template" to "Z:\....\Projects\Job Number Job Name\Dwgs"?

 

Sorry forgot to mention this needs to work in AutoCAD LT2025

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Accepted solutions (1)
1,652 Views
31 Replies
Replies (31)
Message 2 of 32

paullimapa
Mentor
Mentor

Nevermind.. I don't think LT has Reference Manager...

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/changing-path-of-image-xrefs-by-lisp...


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 32

paullimapa
Mentor
Mentor

@h_s_walker updated to work with images

Found this on another thread which should work on LT by SLW210 (Steve Wilson)...give it a try:

https://www.cadtutor.net/forum/topic/90022-change-image-path-in-many-drawings/

 

;;; Updated to accommate for images and not xrefs
;;; Update image paths in a folder of drawings.                                                                                            |
;;;                                                                                                                                        |
;;; https://www.cadtutor.net/forum/topic/90022-change-image-path-in-many-drawings/?do=findComment&comment=649609                           |
;;;                                                                                                                                        |
;;; By SLW210 (Steve Wilson)                                                                                                               |
;;;________________________________________________________________________________________________________________________________________|
;;;                                                                                                                                        |
;;; Original- August 26th, 2024                                                                                                            |
;;;                                                                                                                                        |
;;;________________________________________________________________________________________________________________________________________|
;;;                                                                                                                                        |


(defun c:UPP () (c:UpYourPath))		;; You can change the shortcut to suit what is convenient for you (remember to also change the prompt at the end of the LISP).

(defun c:UpYourPath (/		old-path   new-path   dir
		     files	file	   doc	      model-space
		     paper-space	   imgref     repath    BrowseForFolder
		    )
  ;; Set the old and new paths
  (setq old-path "C:\\***\\****\\Old Path")                     ;; Add your current file path here.
  (setq new-path "C:\\***\\****\\New Path")                     ;; Add the new file path here. 

 (vl-load-com)
; Repath images
; Arguments:
; obj-arg = vl obj
; old-path-arg = original path
; new-path-arg = replacement path
 (defun repath (obj-arg old-path-arg new-path-arg)
      (if
        (and
          (vlax-property-available-p obj-arg 'ImageFile) ; image Object
(eq (strcase (vl-filename-directory (vla-get-ImageFile obj-arg))) (strcase old-path-arg))
        ) 
        (vla-put-ImageFile obj-arg (strcat new-path-arg "\\" (vl-filename-base (vla-get-ImageFile obj-arg)) (vl-filename-extension (vla-get-ImageFile obj-arg))))
       )
 )

 ;; This function is written by Lee Mac and it utilizes the BrowseForFolder method of the Windows Shell Object to provide a dialog interface through which the user may select a directory. 
 ;; Function Syntax: (Browse for Folder)
 ;; Function Returns: FolderPath
 
 (defun BrowseForFolder ( / err fld FolderPath shl slf )
  (setq err (vl-catch-all-apply
    (function (lambda ( / app hwd )
      (if (setq app (vlax-get-acad-object)
        shl (vla-getinterfaceobject app "shell.application")
        hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
        fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) "" 0 ""))
        (setq slf (vlax-get-property fld 'self)
        FolderPath (vlax-get-property slf 'path)
        FolderPath (vl-string-right-trim "\\" (vl-string-translate "/" "\\" FolderPath)))
      ))
    ))
  )
  
  (if slf (vlax-release-object slf))
  (if fld (vlax-release-object fld))
  (if shl (vlax-release-object shl))
  (if (vl-catch-all-error-p err) (prompt (vl-catch-all-error-message err)) FolderPath)
 )
  ;; Prompt user to enter the folder path
  (if (eq "acad" (getvar "program"))
   (setq dir (BrowseForFolder))) ;; Use window to select folder not supported in LT
   (setq dir
    (getstring T
     "\nEnter the folder path containing the DWG files: "
    )
   )                                                              ;; When prompted type in file path to folder of drawings to update.
  )

  ;; Check if folder valid
  (if (not (vl-file-directory-p dir))
    (progn
      (princ "\nInvalid folder. Exiting.")
      (exit)
    )
  )

  ;; Get list of DWG files in the folder
  (setq files (vl-directory-files dir "*.dwg" 1))

  ;; Loop through each file
  (foreach file	files
    (setq doc (vla-open	(vla-get-Documents (vlax-get-acad-object))
			(strcat dir "\\" file)
	      )
    )

    ;; Access model space and paper space
    (setq model-space (vla-get-ModelSpace doc))
    (setq paper-space (vla-get-PaperSpace doc))

    ;; Loop through objects in model space
    (vlax-for obj model-space
     (repath obj old-path new-path) ; use repath function
    )

    ;; Loop through objects in paper space
    (vlax-for obj paper-space
     (repath obj old-path new-path) ; use repath function
    )

    ;; Save and close the drawing
    (vla-save doc)
    (vla-close doc)
  )

  ;; Notify process is complete
  (princ "\nImage paths updated successfully.")
)

(princ
  "\nLoad the script and run 'UPP' or 'UpdateImagePaths' to start."
)(princ)

 

 

 

 

 

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 4 of 32

paullimapa
Mentor
Mentor

If you want to change all images with old paths and replace them with new paths found only in the current drawing, then load & run this lisp function which again should work in LT:

Note: you'll have to update this section of the code to match with your old & new paths:

  ;; Set the old and new paths
  (setq old-path "Z:\\....\\Projects\\Template")                  ;; Add your current file path here.
  (setq new-path "Z:\\....\\Projects\\Job Number Job Name\\Dwgs") ;; Add the new file path here. 

 

Lisp file: UpdImgP.lsp

;;; UpdImgP find all matching image paths in current drawing & replace them
;;; modified from:
;;;                                                                                                                                        |
;;; https://www.cadtutor.net/forum/topic/90022-change-image-path-in-many-drawings/?do=findComment&comment=649609                           |
;;;                                                                                                                                        |
;;; By SLW210 (Steve Wilson)                                                                                                               |
;;;________________________________________________________________________________________________________________________________________|
;;;                                                                                                                                        |
;;; Original- August 26th, 2024                                                                                                            |
;;;                                                                                                                                        |
;;; OP:
;;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-to-change-path-of-certain-images/td-p/13369284

(defun c:UpdImgP (/ doc	model-space new-path old-path paper-space	repath)
  ;; Set the old and new paths
  (setq old-path "Z:\\....\\Projects\\Template")                  ;; Add your current file path here.
  (setq new-path "Z:\\....\\Projects\\Job Number Job Name\\Dwgs") ;; Add the new file path here. 
  
 (vl-load-com)
; Repath images
; Arguments:
; obj-arg = vl obj
; old-path-arg = original path
; new-path-arg = replacement path
 (defun repath (obj-arg old-path-arg new-path-arg)
      (if
        (and
          (vlax-property-available-p obj-arg 'ImageFile) ; image Object
          (eq (strcase (vl-filename-directory (vla-get-ImageFile obj-arg))) (strcase old-path-arg))
        ) 
        (vla-put-ImageFile obj-arg (strcat new-path-arg "\\" (vl-filename-base (vla-get-ImageFile obj-arg)) (vl-filename-extension (vla-get-ImageFile obj-arg))))
      )
 )
    ;; get current acad doc
    (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  
    ;; Access model space and paper space
    (setq model-space (vla-get-ModelSpace doc))
    (setq paper-space (vla-get-PaperSpace doc))

    ;; Loop through objects in model space
    (vlax-for obj model-space
     (repath obj old-path new-path) ; use repath function
    )

    ;; Loop through objects in paper space
    (vlax-for obj paper-space
     (repath obj old-path new-path) ; use repath function
    )

  ;; Notify process is complete
  (princ "\nImage paths updated successfully.")
)
(princ "\nEnter 'UpdImgP' to start.")(princ)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 32

h_s_walker
Mentor
Mentor

@paullimapa unfortunately that won't work. The job number and job name are always changing.

eg I could be working on a drawing with the details 1234 Site A

my colleague could be working on a drawing with the details 7890 Site Z

My colleagues have less lisp knowledge than I do, and asking them to edit the lisp every time is a recipe for disaster

I forgot to mention I need this to happen automatically the first time that the template is saved

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 6 of 32

paullimapa
Mentor
Mentor

Well since you know these three image file names as image1, image 2 and image3 and these are already saved in the project folder location then in theory the code can then search for these specific image file locations and when found save the project folder path as the new path for the images. Then place the code to run at startup so that the next time the dwg is opened from the project folder location these three image paths will be automatically replaced. Though this means the code would have to run each time the dwg opens that would still work when the dwg is opened from the server since the code would find the three images at that location as well. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 32

h_s_walker
Mentor
Mentor

@paullimapa sorry about the VERY LATE getting back.

That won't work.

Sometimes the client asks for the drawing and the problem arises if the client does not use the same directory structure we do, it won't load up the image. That's why I need the path to be relative, then we can tell the client to put all the files in the zip in the same directory.

Also now it's going to be drive J and we only have two images to change on the first save

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 8 of 32

paullimapa
Mentor
Mentor

That's the beauty of having all the files stored in the same directory regardless of the image being attached with full path...

Autocad will look for the image in the same folder as the current drawing so you're good to go.

Give it a test and you're see that it works


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 9 of 32

komondormrex
Mentor
Mentor

@h_s_walker 

i think you need to change the images' paths to relative, maybe like run the following once, once the drawing is saved to a new directory where images 1, 2 and 3 are there.

(setq image_extension ".jpg"
      dwg_path (strcat (getvar 'dwgprefix)) 
)
(foreach image (vl-remove-if-not '(lambda (image) (member (vl-filename-base (vla-get-imagefile image)) '("image1" "image2" "image3")))
		 		  (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "image")))))))
		)
  
  (if (findfile (strcat dwg_path (setq image_name (vl-filename-base (vla-get-imagefile image))) image_extension))
    (vla-put-imagefile image (strcat ".\\" image_name image_extension))
  )
)

 

0 Likes
Message 10 of 32

Sea-Haven
Mentor
Mentor

You can do a reactor trapping SAVE so could check are the image files existing in the dwg directory, if not copy to that directory, there is a VL file copy command.

 

You can embed images in a dwg would that be easier ?

0 Likes
Message 11 of 32

h_s_walker
Mentor
Mentor

I've been going around this the wrong way I think

I've only got two images in the drawing for the sake of argument image1 and image2.

I want to make the path of those two relative.

Can the SAVE and QUICKSAVE commands be edited to make those two image paths relative and then save or quick save?

 

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 12 of 32

komondormrex
Mentor
Mentor

@h_s_walker,

whom you've addressed your last post to?

0 Likes
Message 13 of 32

h_s_walker
Mentor
Mentor

@komondormrex Anyone who has an idea about how to do it

 

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 14 of 32

komondormrex
Mentor
Mentor

well, having done a lisp program to set image path to relative you can implement it in a whatever customizable save* menu item to be first before save command.

0 Likes
Message 15 of 32

h_s_walker
Mentor
Mentor

@komondormrex As I have said before I am not knowledgeable in lisp. I need all the help I can get

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 16 of 32

komondormrex
Mentor
Mentor

the function to set relative path to every image listed as parameter list goes below

(defun make_relative (image_name_list image_extension / image_extension dwg_path image_name image_sset)
	(setq dwg_path (strcat (getvar 'dwgprefix)))
	(foreach image (vl-remove-if-not '(lambda (image) (member (vl-filename-base (vla-get-imagefile image)) image_name_list))
					  (if (setq image_sset (ssget "_x" '((0 . "image")))) 
					  	(mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex image_sset))))
					  )
				   )
  
	  (if (findfile (strcat dwg_path (setq image_name (vl-filename-base (vla-get-imagefile image))) image_extension))
	    (vla-put-imagefile image (strcat ".\\" image_name image_extension))
	  )
	)
	(princ)
)

you can call it like

(make_relative '("image1" "image2") ".jpg")

or add to a quick access bar for instance (not sure if this can be done in lt)

komondormrex_0-1744196462220.png

 

0 Likes
Message 17 of 32

h_s_walker
Mentor
Mentor

@komondormrex I need it do do it automatically ie not typing in the references manually, and I also need it to work whenever a save or quicksave is initiated.

This is where the images are saved

J:\0_Base Directory\0000oooo\Dwg\04_Logos\Image1.png

J:\0_Base Directory\0000oooo\Dwg\04_Logos\Image2.jpg

The resultant drawing will always be saved in the dwg folder.

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 18 of 32

paullimapa
Mentor
Mentor

any reason for storing those image files in a subfolder under Dwg:

Dwg\04_Logos

Your problem will be solved if those images are saved directly under folder Dwg which is where all the rest of the drawing files are saved


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 19 of 32

h_s_walker
Mentor
Mentor

@paullimapa The powers that be want to keep the drawing directory as free from clutter as possible, just the drawings in there.

Howard Walker
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Left Handed and Proud

0 Likes
Message 20 of 32

paullimapa
Mentor
Mentor

The powers that be seem to have mixed standards. Why would they not do the same with the template dwg folder?

Instead of saving images in the same folder as other template files under 

Z:\....\Projects\Template

There should be again a subfolder 

\04_Logos

Then these template files can be modified so the images are attached using relative instead of full paths. Then when the template file is saved from the server into the project folder location with the exact subfolder structure

\04_Logos

the problem would not occur in the first place. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes