Script-Fu for batch image conversion
This discussion is connected to the gimp-user-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Script-Fu for batch image conversion | Dillon | 06 Jun 08:44 |
Script-Fu for batch image conversion | saulgoode@flashingtwelve.brickfilms.com | 06 Jun 12:55 |
Script-Fu for batch image conversion | Dillon | 06 Jun 20:03 |
Script-Fu for batch image conversion | Deniz Dogan | 06 Jun 21:38 |
Script-Fu for batch image conversion | Dillon | 06 Jun 23:15 |
Script-Fu for batch image conversion | Deniz Dogan | 07 Jun 13:40 |
Script-Fu for batch image conversion | Dillon | 07 Jun 18:45 |
Script-Fu for batch image conversion | saulgoode@flashingtwelve.brickfilms.com | 06 Jun 23:46 |
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:\test>gimp-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:\test>gimp-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)
Script-Fu for batch image conversion
Quoting Dillon :
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/etcI 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.
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))
)
)
)
Script-Fu for batch image conversion
2010/6/6 Dillon :
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!
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 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)) )
)
)
Script-Fu for batch image conversion
Quoting Dillon :
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))
)
Script-Fu for batch image conversion
2010/6/6 Dillon :
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 ...
I personally don't think there's much of an advantage using Script-Fu as opposed to ImageMagick when it comes to batch processing. ImageMagick is widely used in all kinds of applications. It also has an abundance of filtering capabilities that you can easily use.
That being said, I'm neither an ImageMagick wizard nor a Script-Fu/GIMP one.
Script-Fu for batch image conversion
That's the conclusion I came to as well. I am still figuring out how to do raw CR2 files, but the script below does handle multi-page TIFFs just fine. It's a PowerShell (Windows) wrapper around ImageMagick. Not elegant, and the formatting on blogger kinda sucks (I'll fix that someday), but here it is:
http://disassemblyrequired.blogspot.com/2010/06/powershell-and-imagemagick.html
The magick all happens with this single command:
- convert image[0].tif image.xcf
Nice.
On Mon, Jun 7, 2010 at 4:40 AM, Deniz Dogan wrote:
2010/6/6 Dillon :
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 couldinsert 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 allmy
manual editing in GIMP, but maybe not any of the batch work ...
I personally don't think there's much of an advantage using Script-Fu as opposed to ImageMagick when it comes to batch processing. ImageMagick is widely used in all kinds of applications. It also has an abundance of filtering capabilities that you can easily use.
That being said, I'm neither an ImageMagick wizard nor a Script-Fu/GIMP one.
--
Deniz Dogan