[Part I. GIMP基礎功]

[Part II. 一種效果的誕生]
[Part III. Script-Fu的秘密]



29.6 熔岩圖,修改成可「單行」執行的 Script-Fu

修改成一行一行可執行的程式碼
  • 本節要將 lava.scm 修改成在 Console 內可一行一行執行的 Scheme 程式碼。
  • lava.scm 完整的程式碼可參考 29.5 節
  • 也可到 GIMP 系統的 scripts 目錄下找到該檔案。
  • 最主要修改的部份是,將「對話框接收輸入變數值」修改成「直接指定輸入變數值」。
  • 先要瞭解,lava.scm 程式碼的執行流程。


最主要修改的部份
  • 不使用 let* 改用 define
  • 原本的程式使用 let* 定義與指定區域變數值。
  • (let* (()()()...) ()() ...) 這樣的語法括號太多。
  • 若要一行一行分析程式碼的意義,let* 語法,括號有好幾層,分析時,會造成一些干擾。
  • 現在不使用 let* 改用 define 來定義與指定變數值。


捨棄函數 script-fu-lava,直接指定輸入變數值
  • 修改成最多的地方就是下列這部份。
  • (if (condition) (expr1) (expr2) .......),要注意此區塊括號的對齊。
  • 記得要刪除多餘的右括號 ) ,不然會出現錯誤訊息。
  • 修改後的程式碼,不再需要預先定義函數 script-fu-lava ,但是要預先設定變數名稱、變數值 。

(define (script-fu-lava image
drawable
seed
tile_size
mask_size
gradient
keep-selection
separate-layer
current-grad)
(let* (
(type (car (gimp-drawable-type-with-alpha drawable)))
(image-width (car (gimp-image-width image)))
(image-height (car (gimp-image-height image)))
(active-selection 0)
(selection-bounds 0)
(select-offset-x 0)
(select-offset-y 0)
(select-width 0)
(select-height 0)
(lava-layer 0)
(active-layer 0)
)


從下列的程式碼得知變數值的型態與大小
SF-IMAGE       "Image"          0
SF-DRAWABLE    "Drawable"       0
SF-ADJUSTMENT _"Seed"           '(10 1 30000 1 10 0 1)
SF-ADJUSTMENT _"Size"           '(10 0 100 1 10 0 1)
SF-ADJUSTMENT _"Roughness"      '(7 3 50 1 10 0 0)
SF-GRADIENT   _"Gradient"       "German flag smooth"
SF-TOGGLE     _"Keep selection" TRUE
SF-TOGGLE     _"Separate layer" TRUE
SF-TOGGLE     _"Use current gradient" FALSE


修改後的程式碼,與測試的結果圖
  • 下面是修改後的程式碼。
  • 啟動 GIMP Script-fu Console
  • 將下面的 Scheme 程式碼,全部選取、複製、再貼入 Script-fu Console 文字框,按下 Enter 。
  • 過一會,就會看到結果圖。


(define width 256)
(define height 256)
(define img (car (gimp-image-new width height RGB)))
(define layer-one (car (gimp-layer-new img width height RGBA-IMAGE "layer 1" 100 NORMAL-MODE)))
(gimp-image-add-layer img layer-one 0)
(gimp-display-new img)

; 前面的程式碼是為了生成「一個透明的圖層」
; 作為之後生成熔岩圖案的參考圖層
; 此參考圖層規範了熔岩圖案的長寬

(define image img) ; 指派影像物件
(define drawable layer-one)  ; 指派圖層物件

(define seed 10)
(define tile_size 10)
(define mask_size 7)
(define gradient "German flag smooth")
(define keep-selection TRUE)
(define separate-layer TRUE)
(define current-grad FALSE)

(define type (car (gimp-drawable-type-with-alpha drawable)))
(define image-width (car (gimp-image-width image)))
(define image-height (car (gimp-image-height image)))
(define active-selection 0)
(define selection-bounds 0)
(define select-offset-x 0)
(define select-offset-y 0)
(define select-width 0)
(define select-height 0)
(define lava-layer 0)
(define active-layer 0)

(gimp-context-push)
(gimp-image-undo-group-start image)

(if (= (car (gimp-drawable-has-alpha drawable)) FALSE)
(gimp-layer-add-alpha drawable)
)

(if (= (car (gimp-selection-is-empty image)) TRUE)
(gimp-selection-layer-alpha drawable)
)

(set! active-selection (car (gimp-selection-save image)))
(gimp-image-set-active-layer image drawable)

(set! selection-bounds (gimp-selection-bounds image))
(set! select-offset-x (cadr selection-bounds))
(set! select-offset-y (caddr selection-bounds))
(set! select-width (- (cadr (cddr selection-bounds)) select-offset-x))
(set! select-height (- (caddr (cddr selection-bounds)) select-offset-y))

(if (= separate-layer TRUE)
(begin
(set! lava-layer (car (gimp-layer-new image select-width select-height type "Lava Layer" 100 NORMAL-MODE)))

(gimp-image-add-layer image lava-layer -1)
(gimp-layer-set-offsets lava-layer select-offset-x select-offset-y)
(gimp-selection-none image)
(gimp-edit-clear lava-layer)

(gimp-selection-load active-selection)
(gimp-image-set-active-layer image lava-layer)
)
)

(set! active-layer (car (gimp-image-get-active-layer image)))

(if (= current-grad FALSE)
(gimp-context-set-gradient gradient)
)

(plug-in-solid-noise RUN-NONINTERACTIVE image active-layer FALSE TRUE seed 2 2 2)
(plug-in-cubism RUN-NONINTERACTIVE image active-layer tile_size 2.5 0)
(plug-in-oilify RUN-NONINTERACTIVE image active-layer mask_size 0)
(plug-in-edge RUN-NONINTERACTIVE image active-layer 2 0 0)
(plug-in-gauss-rle RUN-NONINTERACTIVE image active-layer 2 TRUE TRUE)
(plug-in-gradmap RUN-NONINTERACTIVE image active-layer)

(if (= keep-selection FALSE)
(gimp-selection-none image)
)

(gimp-image-set-active-layer image drawable)
(gimp-image-remove-channel image active-selection)

(gimp-image-undo-group-end image)
(gimp-context-pop)

(gimp-displays-flush)