#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- mode: python; Encoding: utf8n -*-
 
u"""
全レイヤーを円を描くように配置するPython-fuスクリプト
 
by mieki256
 
**動作確認環境
 
- Windows 7 x64
- GIMP 2.8.0 Portable
- GIMP 2.6.11
 
0.0.1  2012.08.07  とりあえず作成。
"""
 
from gimpfu import *
import math
 
def is_old_gimp():
    u"""GIMP 2.6.x上で動かしているか調べる."""
 
    version = pdb.gimp_version()
    if version.startswith("2.6."):
        return True
    if version.startswith("2.4."):
        return True
    else:
        return False
 
def get_layer_ids(layer_ids):
    u"""レイヤーIDリストを再帰で辿って取得する.(GIMP2.8以降用)"""
 
    ids = []
    for i in layer_ids:
        item = gimp.Item.from_id(i)
        if pdb.gimp_item_is_group(item) == 1:
            num_children, child_ids = pdb.gimp_item_get_children(item)
            ids.extend(get_layer_ids(child_ids))
        else:
            ids.append(i)
 
    return ids
 
def python_fu_layers_circle_move(
    image,
    layer,
    radius_v,
    is_crop,
    is_copy,
    num,
    is_rot,
    interpolation,
    supersample,
    recursion_level,
    clip_result,
    auto_center):
    u"""メイン処理."""
 
    is_old = is_old_gimp()
 
    image.undo_group_start() # undoできるようにしておく?
 
    item_layers = []
 
    if is_copy:
        # コピーして配置する場合
 
        # 事前に、選択されているレイヤーを自動切り抜き
        if is_crop:
            pdb.gimp_image_set_active_layer(image, layer)
            pdb.plug_in_autocrop_layer(image, layer)
 
        # 指定枚数分、選択されているレイヤーをコピー
        length = int(num)
        for i in range(length):
            c = layer.copy(True) # コピー
            item_layers.append(c) # レイヤーリストに追加
            image.add_layer(c, -1) # レイヤーを新規作成
 
    else:
        # 既にある全レイヤーを配置する場合
 
        # 全レイヤーのリストを取得
        if is_old:
            # GIMP 2.6 以前
            item_layers = image.layers
 
        else:
            # GIMP 2.8 以降
            ids = get_layer_ids(pdb.gimp_image_get_layers(image)[1])
            for i in ids:
                item_layers.append(gimp.Item.from_id(i))
 
    # 初期角度と角度変化分を設定
    ang = 270.0
    angadd = 360.0 / float(len(item_layers))
    rot = 0.0
    r = float(radius_v)
 
    # 画像の中心を中心座標とする
    cx = float(image.width) / 2
    cy = float(image.height) / 2
 
    for item in item_layers:
        pdb.gimp_image_set_active_layer(image, item)
        rad_ang = math.radians(ang)
        rad_rot = math.radians(rot)
 
        # 自動切り抜き処理.
        # レイヤーコピー有効なら、既に自動切り抜きされているから、
        # その場合は処理しない
        if is_crop and (not is_copy):
            pdb.plug_in_autocrop_layer(image, item)
 
        icx = (r * math.cos(rad_ang)) + cx
        icy = (r * math.sin(rad_ang)) + cy
        x = icx - (float(item.width) / 2)
        y = icy - (float(item.height) / 2)
        item.set_offsets(int(x), int(y)) # レイヤーの表示位置を変更
 
        # 回転処理
        if is_rot:
            pdb.gimp_image_set_active_layer(image, item)
            pdb.gimp_drawable_transform_rotate(item, rad_rot, auto_center, icx, icy, 0, interpolation, supersample, recursion_level, clip_result)
 
        ang += angadd
        rot += angadd
 
    image.undo_group_end()
    gimp.displays_flush() # 画像の表示を更新
    return
 
# ----------------------------------------
# GIMPへのメニュー登録、ダイアログの指定
register(
  "python-fu-layers-circle-move", # プロシジャの名前
  "全レイヤーを円を描くように配置する", # プロシジャの説明文
  "all layers circle move", # PDBに登録する追加情報
  "mieki256", # 作者名
  "Public Domain.", # ライセンス情報
  "2012.08.07", # 作成日
  "<Image>/Layer/全レイヤーを円状に配置", # メニュー表示場所・名前
  "RGB*, GRAY*, INDEXED", # 対応する画像タイプ
 
  # ダイアログの指定
  [
    (PF_VALUE, "radius_v", "半径", 128),
    (PF_TOGGLE, "is_crop", "各レイヤーを自動切り抜きしてから配置", True),
    (PF_TOGGLE, "is_copy", "選択レイヤーをコピーして配置", False),
    (PF_VALUE, "num", "    コピーする枚数", 6),
    (PF_TOGGLE, "is_rot", "各レイヤーを回転させる", False),
    (PF_OPTION, "interpolation", "    補間アルゴリズム", 3, ("NONE", "LINEAR", "CUBIC", "LANCZOS")),
    (PF_TOGGLE, "supersample", "    スーパーサンプリング", True),
    (PF_VALUE, "recursion_level", "    サンプリングレベル", 3),
    (PF_OPTION, "clip_result", "    クリッピング", 0, ("自動調整", "変換前のレイヤーサイズ", "結果で切り抜き", "縦横比で切り抜き")),
    (PF_TOGGLE, "auto_center", "    auto-center", True)
    ],
  [], # 戻り値の定義
 
  python_fu_layers_circle_move # 処理を埋け持つ関数名
  )
 
main() # プラグインを駆動させるための関数
 
最終更新:2012年08月07日 09:55