[Gimp-user] Script-Fu for batch image conversion
Hello folks, I am trying to perform batch conversions of images, including scanned tifs (multi-page), JPGs, and .CR2 raw files. My workflow is as follows: 1) scan/acquire raw images to disk 2) batch convert to XCF 3) hand-edit selected XCFs 4) batch convert to flattened JPG/PNG/etc I am working on a script-fu function for #2, but I'm seeing some odd behavior. When I run the script against JPGs, it creates an XCF for each JPG, but all of the XCFs have the content of the first JPG. I assume I have a scoping problem, or the image variables need to be deleted with each iteration of the while loop, but I'm not having any luck. My second issue is, when I run the script against my scanned 16-bit multi-page TIFs, I get a batch execution failure when calling gimp-image flatten. I haven't started working on the CR2 files yet. Here is the code I'm using: ; START SCRIPT FU (define (batch-save-as-xcf pattern) (let* ( (filelist (cadr (file-glob pattern 1))) (fileparts) (xcfname) (filename) (image) (newimage) (drawable) ) (gimp-message-set-handler 2) (gimp-message Preparing to act on the following files) (gimp-message pattern) (while (pair? filelist) ; set filename to the name of the current file in the glob (set! filename (car filelist)) (gimp-message The current file is: ) (gimp-message filename) ; set xcfname by tokenizing on . and taking everything but the last part (set! fileparts (strbreakup filename .)) (set! fileparts (butlast fileparts)) (set! xcfname (string-append (unbreakupstr fileparts .) .xcf)) (gimp-message The new filename will be: ) (gimp-message xcfname) ; set image from the file, and then get the first layer and set it to newimage (gimp-message Loading File.) (set! image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (set! newimage (car (gimp-image-get-layers image))) ; set drawable to the newimage (gimp-message Setting the Drawable.) (set! drawable (car (gimp-image-flatten newimage))) ; save the drawable from newimage as xcfname (gimp-message Saving the new file.) (gimp-file-save RUN-NONINTERACTIVE newimage drawable xcfname xcfname) (set! filelist (cdr filelist)) ) ) ) ; END SCRIPT FU When I execute it like this: c:\testgimp-2.6 -i -b (batch-save-as-xcf \c:\\test\\*.tif\) -b (gimp-quit 0) I get this output: script-fu.exe-Warning: Preparing to act on the following files script-fu.exe-Warning: c:\test\*.tif script-fu.exe-Warning: The current file is: script-fu.exe-Warning: c:\test\ArroyoSanJose-014.tif script-fu.exe-Warning: The new filename will be: script-fu.exe-Warning: c:\test\ArroyoSanJose-014.xcf script-fu.exe-Warning: Loading File. TIFF image-Warning: Warning: The image you are loading has 16 bits per channel. GIMP can only handle 8 bit, s o it will be converted for you. Information will be lost because of this convers ion. script-fu.exe-Warning: Setting the Drawable. GIMP-Error: Calling error for procedure 'gimp-image-flatten': Procedure 'gimp-image-flatten' has been called with an invalid ID for argument ' image'. Most likely a plug-in is trying to work on an image that doesn't exist a ny longer. batch command experienced an execution error (Type any character to close this window) When I execute it like this: c:\testgimp-2.6 -i -b (batch-save-as-xcf \c:\\test\\*.jpg\) -b (gimp-quit 0) I get this output: script-fu.exe-Warning: Preparing to act on the following files script-fu.exe-Warning: c:\test\*.jpg script-fu.exe-Warning: The current file is: script-fu.exe-Warning: c:\test\019-Arroyo.jpg script-fu.exe-Warning: The new filename will be: script-fu.exe-Warning: c:\test\019-Arroyo.xcf script-fu.exe-Warning: Loading File. script-fu.exe-Warning: Setting the Drawable. script-fu.exe-Warning: Saving the new file. script-fu.exe-Warning: The current file is: script-fu.exe-Warning: c:\test\022-Sunset.jpg script-fu.exe-Warning: The new filename will be: script-fu.exe-Warning: c:\test\022-Sunset.xcf script-fu.exe-Warning: Loading File. script-fu.exe-Warning: Setting the Drawable. script-fu.exe-Warning: Saving the new file. script-fu.exe-Warning: The current file is: script-fu.exe-Warning: c:\test\024-Sunset.jpg script-fu.exe-Warning: The new filename will be: script-fu.exe-Warning: c:\test\024-Sunset.xcf script-fu.exe-Warning: Loading File. script-fu.exe-Warning: Setting the Drawable. script-fu.exe-Warning: Saving the new file. batch command executed successfully (Type any character to close this window) ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user
Re: [Gimp-user] Script-Fu for batch image conversion
Quoting Dillon dillonontheco...@gmail.com: I am trying to perform batch conversions of images, including scanned tifs (multi-page), JPGs, and .CR2 raw files. My workflow is as follows: 1) scan/acquire raw images to disk 2) batch convert to XCF 3) hand-edit selected XCFs 4) batch convert to flattened JPG/PNG/etc I am working on a script-fu function for #2, but I'm seeing some odd behavior. ... ... (set! image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (set! newimage (car (gimp-image-get-layers image))) Substitute 'newimage' for 'image' in the first line, and remove the second line. ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user
Re: [Gimp-user] Script-Fu for batch image conversion
Thanks Saulgoode, that worked! It solved both of my problems. Interesting. I'll have to puzzle through why it worked later, but now I'm on to my next challenge. The reason I'm writing my own script-fu, rather than using Daves Batch Processor, is that my TIF files are multi-page, and when I load the image and flatten it to a drawable, I end up with both pages flattened into one drawable. I only want one of the pages (I think the first). I need to find a way to select that page (which I assume is turned into a layer when the TIF is loaded), and just set that layer to be my drawable. Here's the script, as it's currently written (ignore the commented out lines - I don't have any version control available to me, so this file is full of notes): (define (batch-save-as-xcf pattern) (let* ( (filelist (cadr (file-glob pattern 1))) (fileparts) (xcfname) (filename) (image) (newimage) (drawable) ) (gimp-message-set-handler 2) (gimp-message Preparing to act on the following files) (gimp-message pattern) (while (pair? filelist) ; set filename to the name of the current file in the glob (set! filename (car filelist)) (gimp-message The current file is: ) (gimp-message filename) ; set xcfname by tokenizing on . and taking everything but the last part (set! fileparts (strbreakup filename .)) (set! fileparts (butlast fileparts)) (set! xcfname (string-append (unbreakupstr fileparts .) .xcf)) (gimp-message The new filename will be: ) (gimp-message xcfname) ; set image from the file, and then get the first layer and set it to newimage (gimp-message Loading File.) (set! newimage (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) ;(set! image (car (file-tiff-load RUN-NONINTERACTIVE filename filename))) ;(set! newimage (car (gimp-image-get-layers image))) ; set drawable to the newimage (gimp-message Setting the Drawable.) (set! drawable (car (gimp-image-flatten newimage))) ; save the drawable from newimage as xcfname (gimp-message Saving the new file.) (gimp-file-save RUN-NONINTERACTIVE newimage drawable xcfname xcfname) ;(gimp-image-delete image) ;(gimp-image-delete newimage) (set! filelist (cdr filelist)) ) ) ) ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user
Re: [Gimp-user] Script-Fu for batch image conversion
2010/6/6 Dillon dillonontheco...@gmail.com: Thanks Saulgoode, that worked! It solved both of my problems. Interesting. I'll have to puzzle through why it worked later, but now I'm on to my next challenge. The reason I'm writing my own script-fu, rather than using Daves Batch Processor, is that my TIF files are multi-page, and when I load the image and flatten it to a drawable, I end up with both pages flattened into one drawable. I only want one of the pages (I think the first). I need to find a way to select that page (which I assume is turned into a layer when the TIF is loaded), and just set that layer to be my drawable. I haven't tried this myself, but maybe ImageMagick (the `convert' application) supports that already? Just an idea! -- Deniz Dogan ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user
Re: [Gimp-user] Script-Fu for batch image conversion
Someone off-list suggested ImageMagick. Some googling shows this command: convert mulitple.tif single%d.tif I think this will create multiple files, each representing a page from the tif. Since I planned on wrapping all my script-fu in PowerShell, I could insert a call to imagemagick to create a temp folder of split-up TIFs, which my script-fu could convert to XCF. I'd rather do the whole thing in script-fu, as I anticipate doing some filtering and stuff via GIMP. If I start down the ImageMagick route, I may just go with a PowerShell/ImageMagick approach and leave out the script-fu. Any strong suggestions on going one way or the other? I'll still do all my manual editing in GIMP, but maybe not any of the batch work ... On Sun, Jun 6, 2010 at 11:03 AM, Dillon dillonontheco...@gmail.com wrote: Thanks Saulgoode, that worked! It solved both of my problems. Interesting. I'll have to puzzle through why it worked later, but now I'm on to my next challenge. The reason I'm writing my own script-fu, rather than using Daves Batch Processor, is that my TIF files are multi-page, and when I load the image and flatten it to a drawable, I end up with both pages flattened into one drawable. I only want one of the pages (I think the first). I need to find a way to select that page (which I assume is turned into a layer when the TIF is loaded), and just set that layer to be my drawable. Here's the script, as it's currently written (ignore the commented out lines - I don't have any version control available to me, so this file is full of notes): (define (batch-save-as-xcf pattern) (let* ( (filelist (cadr (file-glob pattern 1))) (fileparts) (xcfname) (filename) (image) (newimage) (drawable) ) (gimp-message-set-handler 2) (gimp-message Preparing to act on the following files) (gimp-message pattern) (while (pair? filelist) ; set filename to the name of the current file in the glob (set! filename (car filelist)) (gimp-message The current file is: ) (gimp-message filename) ; set xcfname by tokenizing on . and taking everything but the last part (set! fileparts (strbreakup filename .)) (set! fileparts (butlast fileparts)) (set! xcfname (string-append (unbreakupstr fileparts .) .xcf)) (gimp-message The new filename will be: ) (gimp-message xcfname) ; set image from the file, and then get the first layer and set it to newimage (gimp-message Loading File.) (set! newimage (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) ;(set! image (car (file-tiff-load RUN-NONINTERACTIVE filename filename))) ;(set! newimage (car (gimp-image-get-layers image))) ; set drawable to the newimage (gimp-message Setting the Drawable.) (set! drawable (car (gimp-image-flatten newimage))) ; save the drawable from newimage as xcfname (gimp-message Saving the new file.) (gimp-file-save RUN-NONINTERACTIVE newimage drawable xcfname xcfname) ;(gimp-image-delete image) ;(gimp-image-delete newimage) (set! filelist (cdr filelist)) ) ) ) ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user
Re: [Gimp-user] Script-Fu for batch image conversion
Quoting Dillon dillonontheco...@gmail.com: The reason I'm writing my own script-fu, rather than using Daves Batch Processor, is that my TIF files are multi-page, and when I load the image and flatten it to a drawable, I end up with both pages flattened into one drawable. I only want one of the pages (I think the first). I need to find a way to select that page (which I assume is turned into a layer when the TIF is loaded), and just set that layer to be my drawable. In that case, you were on the right track originally with using 'gimp-image-get-layers' (I am also assuming multi-page TIFFs load as separate layers). However, you had incorrectly handled the value returned by the function. 'gimp-image-get-layers' returns returns a list containing two elements: the number of layers in the image and an array of the layerIDs of those layers: (set! num-layers (car (gimp-image-get-layers image))) (set! layerIDs (cadr (gimp-image-get-layers image))) You can obtain the layerID of the top layer with: (set! top-layer (vector-ref layerIDs 0)) The next down with: (set! next-layer (vector-ref layerIDs 1)) And so on: (set! bottom-layer (vector-ref layerIDs (- num-layers 1))) If you know the position of the layer you wish to keep (the TIFF page), you can then remove all of the other layers from the image with: (set! pos 0) (while ( pos num-layers) (unless (= pos TIFFpage) (gimp-image-remove-layer image (vector-ref layerIDs pos)) ) (set! i (+ i 1)) ) ___ Gimp-user mailing list Gimp-user@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-user