やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

GIMP python-fu CLI xcfファイル保存する

 xcf形式ファイル保存する。バッチ処理で。

成果物

使い方

git clone https://github.com/ytyaru/Python.Gimp.Save.Xcf.20191218105842
cd Python.Gimp.Save.Xcf.20191218105842/src
./run.sh

コード

run.sh

Run() {
    IsExistCmd() { type "$1" > /dev/null 2>&1; }
    Install() { ! IsExistCmd "$1" && sudo apt -y install "$1"; }
    IsExistPkg() { dpkg -l | grep "$1" > /dev/null 2>&1; }
    InstallPkg() { ! IsExistPkg "$1" && sudo apt -y install "$1"; }
    RunBatch() { gimp --no-interface --console-messages --no-data --no-splash --batch-interpreter python-fu-eval --batch - < "$1"; }
    Install gimp
    InstallPkg gimp-python
    RunBatch "$(cd $(dirname $0); pwd)/save_xcf.py"
}
Run "$@"

save_xcf.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gimpfu import *
img = gimp.Image(512, 512, RGB)
layer = gimp.Layer(img, "layer01", 512, 512, RGBA_IMAGE, 100, NORMAL_MODE)
layer.fill(TRANSPARENT_FILL)
img.add_layer(layer, 0) 
#gimp.Display(img)

import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 512, 512)
ctx = cairo.Context(surface)
ctx.set_source_rgb(1.0, 0.0, 0.0)
ctx.rectangle(128, 128, 256, 256)
ctx.fill()

import struct
def get_rgba_str(bgra_buf):
    rgba_buf = ""
    l = len(bgra_buf)
    for i in range(l / 4):
        i0 = i * 4
        i1 = i0 + 4
        bgra = struct.unpack('@L', src[i0 : i1])[0]
        a = (bgra >> 24) & 0x0ff
        r = (bgra >> 16) & 0x0ff
        g = (bgra >> 8) & 0x0ff
        b = bgra & 0x0ff
        rgba = struct.pack('4B', r, g, b, a)
        rgba_buf += rgba
    return rgba_buf

src = surface.get_data()
dst = get_rgba_str(src)
rgn = layer.get_pixel_rgn(0, 0, 512, 512, True, True)
rgn[0:512, 0:512] = str(dst)
layer.flush()
layer.merge_shadow()
layer.update(0, 0, 512, 512)

import os,sys
dir_path = "/tmp/work/"
try:
    os.makedirs(dir_path)
except: pass
#    import traceback
#    traceback.print_exc()
from datetime import datetime
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
save_path = os.path.join(dir_path, timestamp + ".xcf")
pdb.gimp_xcf_save(0,img,layer,save_path,save_path)
gimp.message("ファイル保存しました。: " + save_path)

#pdb.gimp_displays_flush()
pdb.gimp_quit(1)

実行結果

 /tmp/work/yyyymmddHHMMSS.xcfファイルが作成される。

python-eval.py-警告: Python 2.7.16 (default, Oct 10 2019, 22:02:15) 
[GCC 8.3.0]

python-eval.py-警告: ファイル保存しました。: /tmp/work/20191218125353.xcf

gimp: GEGL-WARNING: (gegl-tile-handler-cache.c:977):gegl_tile_cache_destroy: runtime check failed: (g_queue_is_empty (&cache_queue))
EEEEeEeek! 3 GeglBuffers leaked

気になる点

 #!/usr/bin/env python3としているのに、Python2で実行されている。やはりPython2でないと実行されないのか……。3で書きたいのに。

所感

 これで全自動の画像作成ツールが作れる下地が整った! レイヤーも思いのままに作れるはず。

 編集したければGIMPが使える。レイヤー情報などが残っているxcfファイルなのが嬉しい。

対象環境

$ uname -a
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux