Wednesday, August 12, 2009

Flower Script - save as .scm file

;; abstract-flower-petalCount.scm -- a script for GIMP
;; Author: Joel Jorgensen
;;
;; Creates a flower by making copies of the selected layer (the number of copies
;; being the number of petals specified minus one because you already have the
;; original), offsetting them by the radius specified, and rotating them by
;; successively larger portions of a circle. Used to do the flower art for
;; our wedding.

;; Mmmm, pi. It's just everywhere in this wedding! ^_^
(define *pi* (* 4 (atan 1.0) ) )

;; Recursive function that is the heart of this script.
;; Creates a copy of the (offset-by-the-radius) original layer
;; Adds that as a new layer to the image.
;; Rotates the layer by an amount dependent upon which iteration this is
;; (Each new copy gets rotated farther around)
;; Increments the iteration
;; If it's not done, it recursively calls itself and passes all of the existing
;; stuff plus the new iteration value
;; (The image height is used to determine the pivot point, so each petal is
;; rotated about the center of the image, which is then the center of the
;; flower when all is said and done. Yay math!)
(define (add-petal img petal iteration rotationAmount numPetals)
(let*
(
(newPetal (car (gimp-layer-new-from-drawable petal img)))
(imgHeight (car (gimp-image-height img)))
)

(gimp-image-add-layer img newPetal 0)

(gimp-drawable-transform-rotate newPetal (* iteration rotationAmount) FALSE (/ imgHeight 2) (/ imgHeight 2) TRANSFORM-FORWARD INTERPOLATION-CUBIC FALSE 3 TRANSFORM-RESIZE-CLIP)

(set! iteration (+ iteration 1))

(if (< iteration numPetals)
(add-petal img petal iteration rotationAmount numPetals)
)
)
)

;; The function that starts it all and gets everything set up so that add-petal
;; will have the desired effect.
;; Gets the width of the source petal (the current layer)
;; Calculates the height of the image to be created as being twice
;; the height of the current layer plus the radius offset (twice because
;; we're going around a circle, and so we need to add room for the petals
;; on the other sides)
;; Calculates the petalHeight as half the image height
;; Creates a new image to hold the flower
;; Makes a copy of the source petal
;; Sets the iteration to be the first iteration
;; Calculates the amount to increase the rotation (in radians) each iteration by
;; dividing the number of radians in a rotation by the number of iterations
;; that will be performed (the number of petals)
;; Prevents each step from being undo-able (instead you can undo the whole thing
;; as one bulk operation)
;; Adds the copied petal to the new image
;; Moves it to the center top location
;; Calls add-petal, which kicks off the recursion to create and add the rest
;; of the petals
;; Displayes the new image
;; Re-enables undo for individual steps
(define (abstract-flower srcImg srcPetal radius numPetals)
(let*
(
(width (car (gimp-drawable-width srcPetal)))
(imgHeight (* 2 (+ radius (car (gimp-drawable-height srcPetal)))))
(petalHeight (/ imgHeight 2))
(newImg (car (gimp-image-new imgHeight imgHeight (car (gimp-image-base-type srcImg)))))
(petal (car (gimp-layer-new-from-drawable srcPetal newImg)))
(iteration 1)
(rotationAmount (/ (* 2 *pi*) numPetals))
)

(gimp-image-undo-disable newImg)
(gimp-image-add-layer newImg petal 0)

(gimp-layer-resize petal imgHeight imgHeight (- (/ imgHeight 2) (/ width 2) ) 0)
(gimp-layer-set-offsets petal 0 0)

(add-petal newImg petal iteration rotationAmount numPetals)

(gimp-display-new newImg)

(gimp-image-undo-enable newImg)
)
)

;; Registers this script with the GIMP so that you can actually run it
;; Some descriptive comments for when you're looking for it in the Script
;; Library
;; Set it up to take
;; an IMAGE (the current image)
;; a drawable (the currently selected layer; the source petal)
;; the radius to offset each petal from the center of the flower
;; the number of petals you want in your flower
(script-fu-register "abstract-flower"
"_Abstract Flower"
"Creates a flower by making several copies of the current layer, offsetting them by the amount of the radius, and rotating them different amounts to form a circle. Works best for images with a really sharp border. (Bonus Feature: Can also be used to create snowflakes! ^_^ )"
"Joel Jorgensen "
"Joel Jorgensen"
"2009-01-21"
""
SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 0
SF-ADJUSTMENT "Radius" '(40 0 4096 1 10 0 1)
SF-ADJUSTMENT "Number of Petals" '(10 0 4096 1 10 0 1)
)

;; Adds the script to the menu so you can easily call it
;; (In my version, it actually shows up under Filters > Experimental
(script-fu-menu-register "abstract-flower" "<Toolbox>/Xtns/E_xperimental")

;; EDIT (Don't copy this part) fixed the last line so it will actually add
;; it to a menu instead of throwing some bizarre error about <Prefix>

No comments:

Post a Comment