How do I write a custom auto-crop script using the GIMP?

Stainsor picture Stainsor · Apr 28, 2011 · Viewed 10.1k times · Source

I have a bunch of screen shots and I'd like to crop out the window border. I would like to crop them all using a script.

I have access to the GIMP, but not photoshop so I assumed that the GIMP would be the best tool to use. I have not scripted with the GIMP before, so I looked up some GIMP crop scripts. The ones I found are all similar to what I want, but not quite. I thought it would be a simple matter to alter the script to what I need. But since I am not familiar with the scripting language it is proving more difficult than I thought. I found a great auto crop script here. Can someone help me customize it for what I need?

    (define (script-fu-rs-center-crop filename outfilename width height)

  (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
          (drawable (car (gimp-image-get-active-layer image))))
          (let* ((original-width (car (gimp-image-width image)))
               (original-height (car (gimp-image-height image)))
               (new-width original-width)
               (new-height original-height)
               (offset-x 0)
               (offset-y 0))

               (if (<= (/ original-width original-height) (/ width height))
                   (gimp-image-crop image original-width (* original-width (/ height width)) 0 (/ (- original-height (* original-width (/ height width))) 2) )
                   (gimp-image-crop image (* original-height (/ width height)) original-height (/ (- original-width (* original-height (/ width height))) 2) 0)
               )
           )

  (set! drawable (car (gimp-image-get-active-layer image)))

(gimp-file-save RUN-NONINTERACTIVE image drawable outfilename outfilename)
     (gimp-image-delete image)))

The overall dimensions are not the same for all the photos. But they do all have the same number of pixels on the top, left, right and bottom that I want to crop out. So let's say the image has pixel dimensions width and height and I want to remove t_junk pixels off the top, b_junk pixels off the bottom, l_junk pixels off the left, and r_junk pixels off the right. So I want the new image dimensions to be width - l_junk - r_junk and height - t_junk - b_junk.

Answer

theChrisKent picture theChrisKent · Aug 9, 2011

Edger Script

I have written a custom GIMP script that does exactly what you have asked for. Just paste the following into a text document and save it with a .scm extension in your GIMP scripts folder (the path can be found/created in Edit > Preferences > Folders > Scripts):

(define (script-fu-wirebear-edger filename outfilename top right bottom left)
(let* (
    (img (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
    (owidth (car (gimp-image-width img)))
    (oheight (car (gimp-image-height img)))
    (width (- owidth (+ right left)))
    (height (- oheight (+ top bottom)))
      )

   ;Crop Image
    (gimp-image-crop img width height left top)

   ;Save
    (gimp-file-save RUN-NONINTERACTIVE
        img
        (car (gimp-image-active-drawable img))
        outfilename
        outfilename)

   ;Cleanup
    (gimp-image-delete img)
))
(script-fu-register "script-fu-wirebear-edger"
    "Edger"
    "Removes junk from the edges of an image"
    "Chris Kent"
    "WireBear.com"
    "August 2011"
    "RGB* GRAY*"
    SF-STRING "Filename" ""
    SF-STRING "OutputFilename" ""
    SF-VALUE "TopEdge" "0"
    SF-VALUE "RightEdge" "0"
    SF-VALUE "BottomEdge" "0"
    SF-VALUE "LeftEdge" "0"
)
script-fu-wirebear-edger()

This script takes in the input filename, the output filename and the number of pixels to shave off on each side. You can run the command from Windows (Assuming you have GIMP setup as an environment variable) like this (Be sure to escape special characters as shown and place all on one line):

C:>gimp-2.6 -i -c -b
   "(script-fu-wirebear-edger \"C:\\Users\\You\\Desktop\\Images\\1.png\" 
   \"C:\\Users\\You\\Desktop\\Images\\1_edged.png\" 10 30 25 5)"
   -b "(gimp-quit 0)"

Or you can run it in the Script-Fu Console (Filters > Script-Fu > Console) - regardless of OS like this:

(script-fu-wirebear-edger "C:\\Users\\You\\Desktop\\Images\\1.png" 
"C:\\Users\\You\\Desktop\\Images\\1_edged.png" 10 30 25 5)

Batch Edger Script

In order to run the Edger script on multiple images, you can use the following script in conjunction with the above script (You will need both in your Scripts folder):

(define (script-fu-wirebear-batch-edger pattern outsuffix top right bottom left)
(let* (
    (filelist (cadr (file-glob pattern 1)))
    (filename "")
    (outfn "")
      )
    (while (not (null? filelist))
        (set! filename (car filelist))
        (set! outfn 
            (string-append 
                (string-append 
                    (substring filename 0 (- (string-length filename) 4))
                    outsuffix)
                (substring filename (- (string-length filename) 4))
            )
        )
        (script-fu-wirebear-edger filename outfn top right bottom left)
        (set! filelist (cdr filelist))
    )
))
(script-fu-register "script-fu-wirebear-batch-edger"
    "Batch Edger"
    "Removes junk from the edges of a series of images"
    "Chris Kent"
    "WireBear.com"
    "August 2011"
    "RGB* GRAY*"
    SF-STRING "Pattern" "*.png"
    SF-STRING "OutputSuffix" "_edged"
    SF-VALUE "TopEdge" "0"
    SF-VALUE "RightEdge" "0"
    SF-VALUE "BottomEdge" "0"
    SF-VALUE "LeftEdge" "0"
)
script-fu-wirebear-batch-edger()

The script takes in a search pattern to match target images, a suffix to add to the file name and the number of pixels to shave off on each side of every image. You can run the command from Windows (Assuming you have GIMP setup as an environment variable) like this (Be sure to escape special characters as shown and place all on one line):

C:>gimp-2.6 -i -c -b
   "(script-fu-wirebear-batch-edger \"C:\\Users\\You\\Desktop\\Images\\*.png\" 
   \"_edged\" 10 30 25 5)"
   -b "(gimp-quit 0)"

Or you can run it in the Script-Fu Console (Filters > Script-Fu > Console) - regardless of OS like this:

(script-fu-wirebear-batch-edger "C:\\Users\\You\\Desktop\\Images\\*.png"
"_edged" 10 30 25 5)