手描きからGIMP用作業ファイルに変換

クリップアートを公開するサイトを作ってみた。普段しているどうでもいいラクガキを、何か再利用できる形にしてみようかなと思ったので。

(サイトはある程度できていて、こんな感じになっている。)

まず、適当な紙に描きなぐったラクガキを…
f:id:yamatt2:20140215094219j:plain

普通にスキャンする。自炊用に持っている連続スキャナにポンと突っ込むだけなので楽。

スキャナを接続しているコンピュータと、それ以降の処理をするコンピュータがたまたま別なのだけど、dropboxを使って同期させれば何ら気にならない。

スキャナの仕様では、モノクロのjpeg画像として取り込むようになっている。クリップアートとして扱いやすくするには透過PNGがいいと思ったので、それを目指してGIMPで処理する。

GIMPでやることは、

  • jpeg画像を取り込んで、輪郭をはっきりさせるために二値化処理する。
  • 二値化の結果白(つまり輪郭以外)になったところを、色選択して透明に直す。
  • 輪郭レイヤの下に着色用の不透明レイヤをひとつ敷き、背景っぽい灰色で塗りつぶす。

こんなもの。何度も行うためにscript-fuを書いたが、大体下のようになる。

(define (script-fu-prepare-for-clipart in-filename out-filename)
  (let* (
    (image-id (car (file-jpeg-load 0 in-filename in-filename)))
    (layer-width (car (gimp-image-width image-id)))
    (layer-height (car (gimp-image-height image-id)))
    (drawable-id (vector-ref (cadr (gimp-image-get-layers image-id)) 0))
    (layer-id (car (gimp-layer-new image-id layer-width layer-height 0 "background" 100 0)))
    )

    (if (= 1 (car (gimp-drawable-is-gray drawable-id)))
        (gimp-image-convert-rgb image-id))
    (gimp-threshold drawable-id 157 255)
    (gimp-layer-add-alpha drawable-id)
    (gimp-image-select-color image-id 2 drawable-id "white")
    (gimp-edit-cut drawable-id)
    (gimp-selection-none image-id)
    (gimp-layer-set-name drawable-id "outline")
    (gimp-context-set-background '(230 230 230))
    (gimp-drawable-fill layer-id BACKGROUND-FILL)
    (gimp-image-insert-layer image-id layer-id 0 1)
    ;(gimp-display-new image-id)
    (gimp-xcf-save 0 image-id layer-id out-filename out-filename)
))


(script-fu-register "script-fu-prepare-for-clipart"
  "prepare for clipart..."
  "Load jpeg and save to something"
  "yamamoto tetsuya<mymailaddress@gmailorsomething.com>"
  "yamamoto tetsuya"
  "2013"
  ""
  SF-FILENAME  "Input file name" ""
  SF-STRING  "Output file name" ""
)

;; GIMPのGUIから動作を試してみたければ、下をコメントアウト
;;(script-fu-menu-register "script-fu-prepare-for-clipart"
;;                         "<Image>/File/Create")

この関数は、入力ファイル名(jpeg画像)と出力ファイル名(GIMP用ファイル)を受け取って動作する。コマンドラインから扱いたければ、

gimp -i -d -f -b '(script-fu-prepare-for-clipart "ファイル名1" "ファイル名2")' -b '(gimp-quit 0)'

とかそんな感じに実行する。直接叩いてもいいし、別のプログラムからサブプロセスとして叩いてもいい。

ところで、あとでこのGIMP用画像に着色したあと、作業用のpng画像に一旦変換することも必要になるので、同様にscript-fuを書いた。GIMP用ファイルを開き、レイヤをすべて統合したpngファイルに落とすだけのもの。

(define (script-fu-prepare-for-clipart2 in-filename out-filename)
  (let* (
    (image-id (car (gimp-xcf-load 0 in-filename in-filename)))
    (drawable-id (car (gimp-image-merge-visible-layers image-id 0)))
    )
    (file-png-save 1 image-id drawable-id out-filename out-filename 0 1 0 0 0 0 0)
))

(script-fu-register "script-fu-prepare-for-clipart2"
  "prepare for clipart (2)..."
  "Load xcf and save as png"
  "yamamoto tetsuya<mymailaddress@gmailorsomething.com>"
  "yamamoto tetsuya"
  "2013"
  ""
  SF-FILENAME  "Input file name" ""
  SF-STRING  "Output file name" ""
)

;; GIMPのGUIから動作を試してみたければ、下をコメントアウト
;;(script-fu-menu-register "script-fu-prepare-for-clipart2"
;;                         "<Image>/File/Create")

これら二つのscript-fuは、適当な名前でひとつのファイルにまとめて、GIMPスクリプトフォルダに放り込んでおけば使える。

これが、着色作業中のGIMPの画面で…
f:id:yamatt2:20140215100129j:plain

これが、できあがる実際のPNG画像の一部。
f:id:yamatt2:20140215100404j:plain

クリップアートを切り抜くための目印を含む着色のルールをつくったのだけど、これは次回に書く。