; Ted Shaneyfelt ; ; November 2004 ; Save rotate all layers of the image. ; Start at any angle from -360 to 0, end at any angle from 1 to 360. ; GUI now controls GIF animation settings. ; Angles that differ by multiples of 90 degrees are now optimized for ; faster saving and more consistent quality. ; ; September 2004 ; "Save 360 rotated GIFs" script for GIMP. ; ; This saves copies of an image, rotated at a increments down to 1 degree, ; and saves them to files with suffix 0.gif, 15.gif, 30.gif, 45.gif, ... ; Each filename suffix corresponds with the number of degrees rotated (CCW). ; ; I wrote this tool to create rotated images that I can use with JavaScript ; so I can dynamically choose which direction an image will point on an ; interactive web page. ; ; tvs@hawaii.edu ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; ---------- ; amod - alternate modulus negative and equivalent positive angles have same (amod angle 360) (define (amod x y) (let* ( (m (fmod (abs x) (abs y))) ) (if (or (>= x 0) (= m 0)) m (- (abs y) m) ) ) ) ; seq - sequence containing numbers between start and end with step interval plus extra list (define (seq start end step extra) (if (> start end) extra (seq (+ start step) end step (cons start extra)) ) ) ; grouped-angles - optimize by grouping angles that are multiples of 90 degrees (define (grouped-angles start stop step) (let* ( (normalized-angles (seq 0 90 1 ())) (desired-angles (seq start stop step ())) ) (delq () (mapcar (lambda (normalized-angle) (subset (lambda (angle)(= normalized-angle (amod angle 90))) desired-angles ) ; subset ) ; lambda normalized-angles ) ) ) ) ; remove trailing digits from text (define (strip-trailing-digits name) (if (string-search (substring name (- (length name) 1) (length name) ) "0123456789") (strip-trailing-digits (substring name 0 (- (length name) 1) )) name ) ) ; chop off digits and ".gif" from "filenameprefix360.gif" to get "filenameprefix" (define (strip-n-dot-gif filename) (if (substring-equal? ".gif" filename (- (length filename) 4) (length filename)) (strip-trailing-digits (substring filename 0 (- (length filename) 4) ) ) filename ) ) ; ---------- (define (script-fu-save-rotated-gifs image drawable filenameprefix minrotation maxrotation stepsize interlace loop-infinitely default-delay default-dispose ) (let* ( (grouped-angle-sequence (grouped-angles minrotation maxrotation stepsize)) (deg (/ *pi* -180) ) ) (mapcar (lambda (ilist) (let* ( (img (car (gimp-image-duplicate image))) (layers-collection (gimp-image-get-layers img)) (layers-count (car layers-collection)) ; array length (layers-array (cadr layers-collection)) (j 0) ; array index to current layer (i0 (car ilist)) ) (while (< j layers-count) (let* ( (drw (aref layers-array j)) ; current layer ) (set! drw (aref layers-array j)) (gimp-rotate drw 2 (* i0 deg) ) (if (= 0 (car (gimp-drawable-is-indexed drw))) (gimp-image-convert-indexed img 0 0 255 0 0 "") () ) ; if (set! j (+ j 1)) ) ) (mapcar (lambda (i) (let* ( (filename(string-append (strip-n-dot-gif filenameprefix) (number->string i) ".gif")) (rotate-type (- (amod (+ (/ (- i i0) 90) 4) 2) 1)) ; -1 or GIMP-ROTATE-90 180 270 ) (if (>= rotate-type 0) (gimp-image-rotate img rotate-type) () ) (file-gif-save 1 img 0 filename "" interlace loop-infinitely default-delay default-dispose 0) (set! i0 i) ) ; let ) ; lambda ilist ) ; mapcar (gimp-image-delete img) ) ; let ) ; lambda grouped-angle-sequence ) ; mapcar ) ; let ) ; define (script-fu-register "script-fu-save-rotated-gifs" _"/Script-Fu/Animators/Save rotated GIFs..." "Save rotated GIF image files" "Ted Shaneyfelt" "Ted Shaneyfelt" "September 2004" "" SF-IMAGE "Image" 0 SF-DRAWABLE "Drawable" 0 SF-FILENAME _"Filename prefix" "a0.gif" SF-ADJUSTMENT _"Min. angle (degrees)" '(0 -360 0 1 45 0 1) SF-ADJUSTMENT _"Max. angle (degrees)" '(360 0 360 1 45 0 1) SF-ADJUSTMENT _"Angle step size (degrees)" '(45 1 360 1 5 0 1) SF-TOGGLE _"Interlace" TRUE SF-TOGGLE _"Loop infinitely" TRUE SF-ADJUSTMENT _"Delay (ms)" '(1000 0 604800000 1 100 0 1) SF-OPTION _"Default frame disposal" '("Don't care" "Combine" "Replace") ) ; SF-ADJUSTMENT parameters are: start min max small large float box