Saturday, May 19, 2012

Batch Image Resizing from the GIMP command-line

The following TinyScheme (Script-Fu) script resizes one or more image files as specified with a file glob, and writes the resized image files into an output directory:

(define (scale-to-max-fileglob
         file-pattern
         out-dir
         newmax
         )
  (let* ((filelist (cadr (file-glob file-pattern 1))))
    (while (not (null? filelist))
      (let* ((in-file (car filelist))
             (image (car (gimp-file-load RUN-NONINTERACTIVE in-file in-file)))
             (drawable (car (gimp-image-get-active-drawable image)))
             (old-width (car (gimp-image-width image)))
             (old-height (car (gimp-image-height image)))
             (old-max (max old-width old-height))
             (new-width (round (/ (* old-width newmax) old-max)))
             (new-height (round (/ (* old-height newmax) old-max))))
        ;; http://tinyurl.com/7bvura2 states "... because saving undo
        ;; steps can be time and memory intensive" and so we don't
        ;; care about undo operations for batch runs:
        (gimp-image-undo-disable image)
        (gimp-image-scale image new-width new-height)
        (let ((out-file
               (string-append out-dir
                              ;; Insert a slash character if
                              ;; not already at the tail-end
                              ;; of out-dir:
                              (if (char=? #\/ (car (last (string->list out-dir))))
                                  ""
                                  "/")
                              ;; Take the basename of in-file which may be a fully-qualified path:
                              (car (last (strbreakup in-file "/"))))))
          ;; The print function does not show output on standard
          ;; output, so use gimp-message instead:
          (gimp-message (string-append "   scale-to-max-fileglob: scaling "
                                       in-file " into " out-file
                                       " with these dimensions: "
                                       (number->string new-width) "x" (number->string new-height)))
          (gimp-file-save RUN-NONINTERACTIVE image drawable out-file out-file))
        (gimp-image-delete image))
      (set! filelist (cdr filelist)))))

Store this into ~/.gimp-2.6/scripts/batch-resize.scm and the definition of scale-to-max-fileglob will load into all future gimp sessions.


Example run: This was executed using GIMP 2.6 on a 64-bit Debian Linux machine.  The "script-fu-Warning" is coming from the gimp-message function:



user@somehost:/tmp/images_dir$ time gimp -i -b '(begin (scale-to-max-fileglob "*.jpg" "outdir" 1000) (gimp-quit 0))'

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-43-42_676.jpg into outdir/2012-05-19_16-43-42_676.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-44-35_210.jpg into outdir/2012-05-19_16-44-35_210.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-41-21_785.jpg into outdir/2012-05-19_16-41-21_785.jpg with these dimensions: 1000x562

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-44-02_760.jpg into outdir/2012-05-19_16-44-02_760.jpg with these dimensions: 1000x562

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-45-34_771.jpg into outdir/2012-05-19_16-45-34_771.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-43-15_141.jpg into outdir/2012-05-19_16-43-15_141.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-42-39_886.jpg into outdir/2012-05-19_16-42-39_886.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-45-13_128.jpg into outdir/2012-05-19_16-45-13_128.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-42-52_376.jpg into outdir/2012-05-19_16-42-52_376.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-41-49_429.jpg into outdir/2012-05-19_16-41-49_429.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-42-08_196.jpg into outdir/2012-05-19_16-42-08_196.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-41-54_552.jpg into outdir/2012-05-19_16-41-54_552.jpg with these dimensions: 562x1000

script-fu-Warning:    scale-to-max-fileglob: scaling 2012-05-19_16-42-34_497.jpg into outdir/2012-05-19_16-42-34_497.jpg with these dimensions: 562x1000



real    0m16.179s
user    0m13.229s
sys    0m2.236s




The above code was cobbled together from these sources:
  1. Christopher Campbell's blog: Batch image scaling with Gimp
  2. TinySCHEME Version 1.40 Manual is rather skimpy so you may desire to refer to The Racket Reference instead.
  3. Gimp Batch Mode Introduction

No comments:

Post a Comment