I had asked a question
in this post here about a script to randomly paint dabs based on a specified density map (see examples in that post).
I have cleaned it up, applied some error handling, as well as a bailout threshold (to stop it from going into an infinite loop). The starting point was
this script by Charles Cave.
Here is the final script:
Code:
; random_density_map.scm
; by Rob Antonishen
; http://ffaat.pointclark.net
; Version 1.0 (20080408)
; Description
;
; Script to draw a specified number of random points with the currently
; selected brush, using a density mask.
; Will appear in Filters->Map Menu
;
; based on random.scm
; by Charles Cave <charlesweb@optusnet.com.au>
; http://members.optusnet.com.au/~charles57/GIMP
; License:
;
; 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.
;
; The GNU Public License is available at
; http://www.gnu.org/copyleft/gpl.html
(define (script-fu-random-density-map img inLayer inDensityMap inInvertMap inUseAlpha inIterations inMargin inBailout)
(let* (
(x1 0)
(y1 0)
(ctr 0)
(x2 (car (gimp-drawable-width inLayer)))
(y2 (car (gimp-drawable-height inLayer)))
(xMap (car (gimp-drawable-width inDensityMap)))
(yMap (car (gimp-drawable-height inDensityMap)))
(x 0)
(y 0)
(map-type 0)
(get-val 0)
(test 0)
(thresh 0)
(*randompoint* (cons-array 2 'double))
(drw-width 0)
(drw-height 0)
(lc 0)
)
; define drawable area for the algorithm
(set! x1 (+ x1 inMargin))
(set! x2 (- x2 inMargin))
(set! y1 (+ y1 inMargin))
(set! y2 (- y2 inMargin)) (set! drw-width (- x2 x1))
(set! drw-height (- y2 y1))
;get map type: RGB-IMAGE (0), RGBA-IMAGE (1), GRAY-IMAGE (2), GRAYA-IMAGE (3), INDEXED-IMAGE (4), INDEXEDA-IMAGE (5)
(set! map-type (car (gimp-drawable-type inDensityMap)))
; make sure maps isn't indexed
(if (or (= map-type INDEXED-IMAGE) (= map-type INDEXEDA-IMAGE))
(gimp-message "Density Map can not be indexed!") ; error
(if (or (not (= x2 xMap)) (not (= y2 yMap)))
(gimp-message "Density Map must be the same size as the active layer!") ; error
;it begins here
(begin
(gimp-context-push)
(gimp-image-undo-group-start img)
; set up progress bar
(gimp-progress-set-text _"Rendering Random masked Image")
(while (and (< ctr inIterations) (< lc inBailout))
; get a random location
(set! x (+ x1 (random drw-width )))
(set! y (+ y1 (random drw-height)))
; get the pixel value at that spot
(set! get-val (cadr (gimp-drawable-get-pixel inDensityMap x y)))
; pick a number, any number
(set! thresh (random 255))
(if (and (= inUseAlpha TRUE) (= (car (gimp-drawable-has-alpha inDensityMap)) TRUE)) ; if using alpha
(begin
(set! test (aref get-val 3)) ; test threshold against alpha ( index 3)
(gimp-context-set-foreground (list (aref get-val 0) (aref get-val 1) (aref get-val 2))) ;set brush colour
)
(if (or (= map-type GRAY-IMAGE) (= map-type GRAYA-IMAGE)) ; else if greyscale
(set! test (aref get-val 0)) ; test threshold against colour ( index 0)
(if (or (= map-type RGB-IMAGE) (= map-type RGBA-IMAGE)) ; else if colour
(set! test (/ (+ (aref get-val 0) (aref get-val 1) (aref get-val 2)) 3)) ; test threshold against average of r g and b
(set! test 255) ; else threshold to full value (always draw)
)
)
)
(if (= inInvertMap TRUE) ; reverse the map if invert option
(set! test (- 255 test))
)
(if (< thresh test) ; compare threshold against random value
(begin
(set! ctr (+ ctr 1)) ; increment counter
(set! lc 0)
(aset *randompoint* 0 x) ; set the paint array
(aset *randompoint* 1 y)
(gimp-paintbrush-default inLayer 2 *randompoint*) ; paint point
(gimp-progress-update (/ ctr inIterations)) ;update progress bar
)
)
(set! lc (+ lc 1))
)
(if (>= lc inBailout)
(gimp-message "Bailout Parameter Exceeded - Aborted!") ; error
)
(gimp-progress-end)
(gimp-image-undo-group-end img)
(gimp-displays-flush)
(gimp-context-pop)
)
)
)
)
)
(script-fu-register "script-fu-random-density-map"
"<Image>/Filters/Map/Random Density Map..."
"Draw a specified number of random points with the currently selected brush, using a density mask."
"Rob Antonishen"
"Rob Antonishen"
"April 2008"
"RGB*, GRAY*"
SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 0
SF-DRAWABLE "Density Map" -1
SF-TOGGLE "Invert Map" FALSE
SF-TOGGLE "Use map alpha channel for Density and draw with map colour" FALSE
SF-ADJUSTMENT "Number of points to draw" '(10 1 10000 10 100 0 0)
SF-ADJUSTMENT "Border Margin (pixels)" '(0 0 100 1 6 0 0)
SF-ADJUSTMENT "Bailout Threshold" '(200 100 2000 10 100 0 0)
)
It uses the currently selected tool.
The density map can either be a greyscale map, in which case it will draw with the current pen and colour, or a layer with transparency. In that case, it will use the alpha for density and paint using the colour of the layer with transparency. See the examples in the other thread.
-Rob A>