[Part I. GIMP基礎功]

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



顯示具有 第26章 小島圖案(Land) 標籤的文章。 顯示所有文章
顯示具有 第26章 小島圖案(Land) 標籤的文章。 顯示所有文章

26.1 執行Script-Fu,產生小島圖案

  • Land,在2.2版時,譯詞是「陸地」。
  • Patterns,在2.2版時,譯詞是「圖樣」。


預設值之下的小島圖案
  • 執行[影像] / 檔案 / 建立 / Patterns / Land【註1】,使用預設的參數,可產生小島與海水的圖案。
  • 試試不同的參數,尤其是「漸層」這個參數,你將有意想不到的新發現。
  • 下圖是「Script-Fu:Land」對話盒,使用預設參數,執行後,可產生綠色的島嶼淡藍色的海水的圖案。


下圖是「Script-Fu:Land」執行後的小島圖案。



驗證無縫鋪排的效果
  • 執行[影像] / 濾鏡 / 映射 / 鋪排【註2】,產生2x2個小島並排的新圖案。
  • 如此,可確認小島圖案為無接縫的圖樣。



選單及項目名稱的英文:
【註1】[Image] / File / Create / Patterns / Land
【註2】[Image] / Filters / Map / Tile

26.2 島嶼的成因

分三方面討論:
1. 海岸線曲折的成因
  • 雲霧是利用隨機分佈產生的,要產生明顯的海岸輪廓。
  • 雲霧的濃密程度要配合,因此,要調整圖案的明暗分佈。
  • 換色時,採用的漸層,要適合該雲霧圖。
2. 陸海的顏色
  • 黑白雲霧退去,轉為地綠海藍的景致,是利用 Gradient Map 濾鏡,要選用 Land 1 漸層。
3. 立體的視效
  • 是使用凹凸貼圖濾鏡(Bump Map)。

簡而言之,島嶼,其浮現方式在於,雲去霧散、地綠海藍、陸升水沉。


1. 海岸線曲折的成因
  • 明顯的海岸輪廓,是由於重新調整過雲霧的濃密程度。
  • 海岸線的成因,是因為雲霧圖隨機的特性,及綠藍漸層的中間是深褐色。
  • 下圖是執行 Stretch Contrast 之後的圖案,調整圖案的明暗分佈。



2. 陸海的顏色
  • 放大的 Land 1 漸層。


  • 選用 Land 1 漸層,執行 Gradient Map 之後的圖案。

26.3 一步一步做,讓雲霧消失

以下,操作 GIMP 圖形介面,一步一步做,生成小島圖案。
藉由這過程,瞭解程式碼的意思。


Step 1.
  • 執行[影像] / 檔案 / 新增【註1】,新增一個透明底色256x256影像,圖層更名為 bottom 。

  • 對應的程式碼
35: (img (car (gimp-image-new width height RGB)))
36: (layer-one (car (gimp-layer-new img width height
37: RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
38: (layer-two 0)


Step 2.
  • 執行[影像] / 濾鏡 / 描繪 / 雲狀 / Solid Noise【註2】,勾選「可鋪排」選項,不勾選「湍流」選項,產生灰階霧狀效果。勾選可鋪排選項,產生的圖案是無接縫的圖案。


  • 對應的程式碼
42: (gimp-image-add-layer img layer-one 0)
43:
44: (plug-in-solid-noise RUN-NONINTERACTIVE img layer-one TRUE FALSE seed detail xscale yscale)


Step 3.
  • 執行[影像] / 色彩 / 自動 / Stretch Contrast【註3】,增強明暗對比。

  • 對應的程式碼
45: (plug-in-c-astretch RUN-NONINTERACTIVE img layer-one)


Step 4.
  • 複製 Bottom 圖層,得到新圖層「Bottom 複製本」。
  • 在英文介面裡,「Bottom 複製本」相當於 Bottom Copy

  • 對應的程式碼
46: (set! layer-two (car (gimp-layer-copy layer-one TRUE)))
47: (gimp-image-add-layer img layer-two -1)
48: (gimp-image-set-active-layer img layer-two)


Step 5.
  • 在漸層面版內,選擇 Land 1 漸層。
  • 對「Bottom 複製本」,執行[影像] / 色彩 / 映射 / Gradient Map【註4】,使用 Land 1 漸層,將黑白圖案變成彩色的圖案。


  • 對應的程式碼
50: (plug-in-gradmap RUN-NONINTERACTIVE img layer-two)


選單及項目名稱的英文:
【註1】[Image] / File / New
【註2】[Image] / Filters / Render / Clouds / Solid Noise,勾選Tilable,不勾選Turbulent
【註3】[Image] / Colors / Auto / Stretch Contrast
【註4】[Image] / Colors / Map / Gradient Map
注意!
在2.6.7版,Clouds的譯詞是「雲朵」,之前的版本是「雲狀」,我個人偏好「雲狀」一詞。 在2.6.7版,Colors的譯詞是「顏色」(作為選單時),之前的版本是「色彩」,我個人偏好「色彩」一詞。

26.4 一步一步做,讓島嶼隆起

接續前一節,繼續以圖形使用者介面來生成小島的圖案,只是步驟從新編號,從1號開始編號。


Step 1.
  • 對 Bottom 圖層,執行[影像] / 選擇 / 依顏色【註1】,此功能其實是「依顏色選擇按鈕工具」,在工具選項面版內,界限值(Threshold)設55,將灰階為190的灰色及其附近的顏色選住。

  • 對應的程式碼
54: (gimp-by-color-select layer-one '(190 190 190) 55 CHANNEL-OP-REPLACE FALSE FALSE 0 FALSE)


Step 2.
  • 對bottom Copy圖層,執行[影像] / 濾鏡 / 映射 / 凹凸貼圖【註2】,Bump Map圖層設bottom圖層,其餘參數在對話盒中為預設值,即Map Type選線性(Linear),勾選Compensation for Darkening,Azimuth設為135,Elevation設為35,深度(Depth)設為60(對應landheight變數),其餘設為 0。

  • 對應的程式碼
55: (plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 landheight 0 0 0 0 TRUE FALSE 0)


Step 3, 4, & 5.
  • 3. 執行[影像] / 選擇 / 相反【註3】,將選取區域反轉。
  • 4. 對「Bottom複製本」,執行[影像] / 濾鏡 / 映射 / 凹凸貼圖【註4】,Bump Map圖層設為bottom圖層,其餘參數在對話盒中為預設值,即Map Type選線性(Linear),勾選Compensation for Darkening,Azimuth設為135,Elevation設為35,深度(Depth)設為4(對應seadepth變數),其餘設為0。
  • 5. 執行[影像] / 選擇 / 全部不選【註5】,釋放選取區域。

  • 前面三步驟,對應到的程式碼
58: (gimp-selection-invert img)
59: (plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 seadepth 0 0 0 0 TRUE FALSE 0)


最終結果
  • 下圖展示了 land.scm 最終的執行結果。

  • 下圖展示了最終的圖層結構。



選單及項目名稱的英文:
【註1】[Image] / Select / By Color
【註2】[Image] / Filters / Map / Bump Map
【註3】[Image] / Select / Invert
【註4】[Image] / Filters / Map / Bump Map
【註5】[Image] / Select / None

26.5 程式land.scm分三部份

若要徹底瞭解land.scm,可仿傚第22章的方式,單步執行,來分析每一行程式碼的作用。

若用PSPad開啟程式檔(或任何文字編輯器),看到的Script-Fu程式碼,變數會對得很整齊。HTML會把大量的空白省略,因此程式碼的排版變成了下面這樣子。我替Script-Fu程式碼加上行號乎,方便讀者閱讀。

程式land.scm分三部份:
  • 1~32行:註解,功能說明與版權聲明。
  • 33~70行:定義函式。
  • 71~91行:註冊函式。
請注意,有幾行程式(57、61、73)有註解符號,沒有作用。
第1到第32行:註解說明1: ; GIMP - The GNU Image Manipulation Program
2: ; Copyright (C) 1995 Spencer Kimball and Peter Mattis
3: ;
4: ; Land --- create a pattern that resembles a Topographic map
5: ; Copyright (C) 1997 Adrian Karstan Likins
6: ; aklikins@eos.ncsu.edu
7: ;
8: ;
9: ; This script works on the current gradient you have loaded.
10: ; Some suggested gradients:
11: ; Land (produces a earthlike map)
12: ; Brushed_aluminum (looks like the moon)
13: ;
14: ;
15: ; Thanks to Quartic for helping me debug this thing.
16: ;
17: ; This program is free software; you can redistribute it and/or modify
18: ; it under the terms of the GNU General Public License as published by
19: ; the Free Software Foundation; either version 2 of the License, or
20: ; (at your option) any later version.
21: ;
22: ; This program is distributed in the hope that it will be useful,
23: ; but WITHOUT ANY WARRANTY; without even the implied warranty of
24: ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25: ; GNU General Public License for more details.
26: ;
27: ; You should have received a copy of the GNU General Public License
28: ; along with this program; if not, write to the Free Software
29: ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30:
31:
32:

第33到第70行:定義函式
33: (define (script-fu-land width height seed detail landheight seadepth xscale yscale gradient)
34: (let* (
35: (img (car (gimp-image-new width height RGB)))
36: (layer-one (car (gimp-layer-new img width height
37: RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
38: (layer-two 0)
39: )
40: (gimp-context-set-gradient gradient)
41: (gimp-image-undo-disable img)
42: (gimp-image-add-layer img layer-one 0)
43:
44: (plug-in-solid-noise RUN-NONINTERACTIVE img layer-one TRUE FALSE seed detail xscale yscale)
45: (plug-in-c-astretch RUN-NONINTERACTIVE img layer-one)
46: (set! layer-two (car (gimp-layer-copy layer-one TRUE)))
47: (gimp-image-add-layer img layer-two -1)
48: (gimp-image-set-active-layer img layer-two)
49:
50: (plug-in-gradmap RUN-NONINTERACTIVE img layer-two)
51:
52:
53:
54: (gimp-by-color-select layer-one '(190 190 190) 55 CHANNEL-OP-REPLACE FALSE FALSE 0 FALSE)
55: (plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 landheight 0 0 0 0 TRUE FALSE 0)
56:
57: ;(plug-in-c-astretch RUN-NONINTERACTIVE img layer-two)
58: (gimp-selection-invert img)
59: (plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 seadepth 0 0 0 0 TRUE FALSE 0)
60:
61: ;(plug-in-c-astretch RUN-NONINTERACTIVE img layer-two)
62:
63: ; uncomment the next line if you want to keep a selection of the "land"
64: (gimp-selection-none img)
65:
66: (gimp-display-new img)
67: (gimp-image-undo-enable img)
68: )
69: )
70:

第71到第91行:註冊函式
71: (script-fu-register "script-fu-land"
72: _"_Land..."
73: _"Create an image filled with a topographic map pattern"
74: "Adrian Likins <aklikins@eos.ncsu.edu>"
75: "Adrian Likins"
76: "1997"
77: ""
78: SF-ADJUSTMENT _"Image width" '(256 10 1000 1 10 0 1)
79: SF-ADJUSTMENT _"Image height" '(256 10 1000 1 10 0 1)
80: SF-ADJUSTMENT _"Random seed" '(32 0 15000000 1 10 0 1)
81: SF-ADJUSTMENT _"Detail level" '(4 1 15 1 5 0 0)
82: SF-ADJUSTMENT _"Land height" '(60 1 65 1 10 0 1)
83: SF-ADJUSTMENT _"Sea depth" '(4 1 65 1 10 0 1)
84: SF-ADJUSTMENT _"Scale X" '(4 0.1 16 1 5 0.1 0)
85: SF-ADJUSTMENT _"Scale Y" '(4 0.1 16 1 5 0.1 0)
86: SF-GRADIENT _"Gradient" "Land 1"
87: )
88:
89: (script-fu-menu-register "script-fu-land"
90: "<Image>/File/Create/Patterns")
91:

26.6 島嶼圖,修改成可「單行」執行的 Script-Fu

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


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


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

(define (script-fu-land width height seed detail landheight seadepth xscale yscale gradient)
(let* (
  (img (car (gimp-image-new width height RGB)))
  (layer-one (car (gimp-layer-new img width height
                                  RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
  (layer-two 0)
  )


從下列的程式碼得知變數值的型態與大小
SF-ADJUSTMENT _"Image width"  '(256 10 1000 1 10 0 1)
SF-ADJUSTMENT _"Image height" '(256 10 1000 1 10 0 1)
SF-ADJUSTMENT _"Random seed"  '(32 0 15000000 1 10 0 1)
SF-ADJUSTMENT _"Detail level" '(4 1 15 1 5 0 0)
SF-ADJUSTMENT _"Land height"  '(60 1 65 1 10 0 1)
SF-ADJUSTMENT _"Sea depth"    '(4 1 65 1 10 0 1)
SF-ADJUSTMENT _"Scale X"      '(4 0.1 16 1 5 0.1 0)
SF-ADJUSTMENT _"Scale Y"      '(4 0.1 16 1 5 0.1 0)
SF-GRADIENT   _"Gradient"     "Land 1"


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


(define width 256 )
(define height 256 )
(define seed 32 )
(define detail 4 )
(define landheight 60 )
(define seadepth 4 )
(define xscale 4 )
(define yscale 4 )
(define gradient "Land 1")

(define img (car (gimp-image-new width height RGB)))
(define layer-one (car (gimp-layer-new img width height RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
(define layer-two 0)

(gimp-context-set-gradient gradient)
(gimp-image-undo-disable img)
(gimp-image-add-layer img layer-one 0)

(plug-in-solid-noise RUN-NONINTERACTIVE img layer-one TRUE FALSE seed detail xscale yscale)
(plug-in-c-astretch RUN-NONINTERACTIVE img layer-one)
(set! layer-two (car (gimp-layer-copy layer-one TRUE)))
(gimp-image-add-layer img layer-two -1)
(gimp-image-set-active-layer img layer-two)

(plug-in-gradmap RUN-NONINTERACTIVE img layer-two)



(gimp-by-color-select layer-one '(190 190 190) 55 CHANNEL-OP-REPLACE FALSE FALSE 0 FALSE)
(plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 landheight 0 0 0 0 TRUE FALSE 0)

;(plug-in-c-astretch RUN-NONINTERACTIVE img layer-two)
(gimp-selection-invert img)
(plug-in-bump-map RUN-NONINTERACTIVE img layer-two layer-one 135.0 35 seadepth 0 0 0 0 TRUE FALSE 0)

;(plug-in-c-astretch RUN-NONINTERACTIVE img layer-two)

; uncomment the next line if you want to keep a selection of the "land"
(gimp-selection-none img)

(gimp-display-new img)
(gimp-image-undo-enable img)

26.7 島嶼圖,修改成可「單行」執行的 Python-Fu

修改後的程式碼,與測試的結果圖
  • 啟動 GIMP Python Console
  • 將下面的程式碼,全部選取、複製、再貼到 Python Console 提示符號 >>> 之後,按下 Enter 。
  • 過一會,就會看到結果圖。
width = 256
height = 256
seed = 32
detail = 4
landheight = 60
seadepth = 4
xscale = 4
yscale = 4
gradient = "Land 1"

img = pdb.gimp_image_new(width, height, RGB)
layer_one = pdb.gimp_layer_new(img, width, height, RGB_IMAGE, "Bottom", 100, NORMAL_MODE)
layer_two = 0

pdb.gimp_context_set_gradient(gradient)
pdb.gimp_image_undo_disable(img)
pdb.gimp_image_add_layer(img, layer_one, 0)

pdb.plug_in_solid_noise(img, layer_one, TRUE, FALSE, seed, detail, xscale, yscale)
pdb.plug_in_c_astretch(img, layer_one)
layer_two = pdb.gimp_layer_copy(layer_one, TRUE)
pdb.gimp_image_add_layer(img, layer_two, -1)
pdb.gimp_image_set_active_layer(img, layer_two)

pdb.plug_in_gradmap(img, layer_two)

pdb.gimp_by_color_select(layer_one, (190, 190, 190), 55, CHANNEL_OP_REPLACE, FALSE, FALSE, 0, FALSE)
pdb.plug_in_bump_map(img, layer_two, layer_one, 135.0, 35, landheight, 0, 0, 0, 0, TRUE, FALSE, 0)

#pdb.plug_in_c_astretch(img, layer_two)
pdb.gimp_selection_invert(img)
pdb.plug_in_bump_map(img, layer_two, layer_one, 135.0, 35, seadepth, 0, 0, 0, 0, TRUE, FALSE, 0)

#pdb.plug_in_c_astretch(img, layer_two)

# uncomment the next line if you want to keep a selection of the "land"
pdb.gimp_selection_none(img)

pdb.gimp_display_new(img)
pdb.gimp_image_undo_enable(img)

26.8 島嶼圖,摸索轉碼的過程,與須注意的語法特點

  • 本節介紹單步執行的「第三種方式」,修改成在 Console 內可一行一行執行的 Python 程式碼 。
  • 接續前節,使用前節更改後的 Scheme 程式碼,將它改成 Python 程式碼 。


修改「變數值指派」的程式碼
  • 有些地方,可以直接手動更改。有些地方,手動更改,太累人了。
  • 文字編輯器,都有「搜尋」與「取代」的功能,善用「搜尋」與「取代」,可幫助修改程式碼。

(define width 256 )
(define height 256 )
(define seed 32 )
(define detail 4 )
(define landheight 60 )
(define seadepth 4 )
(define xscale 4 )
(define yscale 4 )
(define gradient "Land 1")

  • 可分段使用「搜尋」與「取代」的功能。
  • 例如,上一段程式碼是用於「變數值指派」。
    • (define ...) 開頭的 (define 是要刪除的
    • (define ...) 結尾的 ) 是要刪除的
    • 將「空白」取代為 等號 =
  • 「取代」之後的程式碼,如下所示。

width = 256
height = 256
seed = 32
detail = 4
landheight = 60
seadepth = 4
xscale = 4
yscale = 4
gradient = "Land 1"


修改「指派影像物件、圖層物件」的程式碼

(define img (car (gimp-image-new width height RGB)))
(define layer-one (car (gimp-layer-new img width height RGB-IMAGE "Bottom" 100 NORMAL-MODE)))
(define layer-two 0)

  • 上一段程式碼是用於「指派影像物件、圖層物件」。
    • (define ...) 開頭的 (define 是要刪除的
    • (define ...) 結尾的 ) 是要刪除的
    • 利用換行符號的逃脫字符 \n 可輕鬆刪除結尾的 ) ,也就是,在文字編輯器「取代」功能的對話框內,將 )\n 取代為 \n
    • 將 (car 取代為 等號 =
    • 將(...... layer-two 0)「空白」取代為 等號 =
    • 將剩餘的「空白」取代為 "逗點加空白"「, 」
    • 將 (gimp 取代為 pdb.gimp
    • 將 減號 - 取代為 _ 底線
  • 其它不符合 Python 語法之處,直接手動更改。
  • 「取代」之後的程式碼如下所示。

img = pdb.gimp_image_new(width, height, RGB)
layer_one = pdb.gimp_layer_new(img, width, height, RGB_IMAGE, "Bottom", 100, NORMAL_MODE)
layer_two = 0


特別須注意之處
  • 接下來,主要修改之處,就是將 Scheme 的函數改成 Python 的函數。
  • (plug-in-gradmap ......) 改成 pdb.plug_in_gradmap(......)
  • 原本 Scheme code 參數值的指派方式是
(plug-in-gradmap RUN-NONINTERACTIVE img layer-two)
  • Python code 函數 pdb.plug_in_gradmap 參數值的指派
    • 第1個參數不是 RUN_NONINTERACTIVE
    • 第1個參數是 img
    • 第2個參數是 layer_two
    • 第3個參數是關鍵字參數(Keyword parameter)的形式,因此,可有可無,因為預設已是 RUN_NONINTERACTIVE 。
  • 因為 Gradient Map 原本就沒有圖形介面。
  • 改用高斯模糊濾鏡為例。
    • pdb.plug_in_gauss_iir(img, text_mask, blur_radius, 1, 1, run_mode=RUN_INTERACTIVE)
    • run_mode = RUN_INTERACTIVE,會出現濾鏡對話盒。
    • run_mode = RUN_NONINTERACTIVE,是預設的情況,不會出現濾鏡對話盒。