Friday, July 18, 2014

GIMP Script Fu: Rectangular Grid (also, Scheme vectors)

Here is another quick script I whipped up for The GIMP. This one takes a width and a height, and draws you a grid with rectangles of the specified size.

The most interesting thing about the script is not what it does, but how it handles vectors. What little GIMP documentation I could find tells me to use cons-array and aset to build up an array for the gimp-pencil function. This offended my delicate sensibilities. Surely I can build a literal to pass into the function, and not have to generate the array iteratively! It turns out I can. If you hashtag something, it will build you a vector that gimp-pencil expects.

The script also demonstrates the use of Scheme's backquote operator. My vector is not actually fully constant; it depends on the input width/height. You cannot construct a vector directly like you would want to, because instead of containing the evaluated value of (- width 1), it will contain the literal closure of (- width 1). I am probably maligning the technical aspect, but suffice it to say, if you put a backquote before your vector literal, and a comma before the functions you want to evaluate before building the vector, it does The Right Thing (TM).

(define
 (script-fu-rectangle-grid image layer width height)
 (let*
  (
  )
  
  ; Input validation ;
  (set! width (max width 3))
  (set! height (max height 3))
  
  (gimp-context-push)
  (gimp-undo-push-group-start image)
  
  ; Implementation goes here ;
  
  (gimp-layer-resize-to-image-size layer)  
  (gimp-layer-resize layer width height 0 0)
  
  (gimp-layer-add-alpha layer)
  (gimp-drawable-fill layer TRANSPARENT-FILL)
  
  (gimp-context-set-brush "Pixel (1x1 square)")
  (gimp-context-set-foreground '(0 0 0))   
  
  (gimp-pencil layer 10 `#(
    0            0
    0            ,(- height 1)
    ,(- width 1) ,(- height 1)
    ,(- width 1) 0
    0            0
   )
  )
  (plug-in-tile RUN-NONINTERACTIVE image layer (car (gimp-image-width image)) (car (gimp-image-height image)) FALSE)
  
  (gimp-layer-set-opacity layer 20)
  (gimp-layer-set-mode layer NORMAL-MODE)
  
  (gimp-undo-push-group-end image)
  (gimp-context-pop)
  (gimp-displays-flush)
 )
)

(script-fu-register
 "script-fu-rectangle-grid"
 "Grid"
 "Sets the contents of a layer to be a semi-transparent grid of rectangles."
 "The Unary Heap"
 "The Unary Heap"
 "2014-07-16"
 "RGB*"

 SF-IMAGE      "Image"             0
 SF-DRAWABLE   "Drawable"          0
 SF-VALUE      "Width"            "16"
 SF-VALUE      "Height"            "8"
)

(script-fu-menu-register
 "script-fu-rectangle-grid"
 "<Image>/Filters/UnaryHeap"
)

I'm not including a screenshot of the output of this one; it's pretty boring.

No comments:

Post a Comment