LoginSignup
0
2

More than 5 years have passed since last update.

GIMPのScript-Fuで画像の切り取りを自動化するためマスク画像から座標を出力する

Posted at

画像の特定の範囲の形状を繰返し切り取りたい際、GIMPのScript-Fuを利用していますが、新たに作りたい場合、マスク画像からスクリプトを生成したいと思い立ちました。
マスク画像から座標を出力するようなコードが見つからなかったため、簡易的なものを作ってみました。
速度等考えていないので、あまり利口な方法ではないかもしれませんが、こんな内容となりました。

ソースコード

private RectList MaskToRect(string filePath)
{
    Bitmap bmp = new Bitmap(filePath);
    RectList list = new RectList();

    toolStripProgressBar1.Maximum = bmp.Size.Height;
    toolStripProgressBar1.Value = 0;

    for (int y = 0; y < bmp.Size.Height; y++)
    {
        for (int x = 0; x < bmp.Size.Width; x++)
        {
            if (list.Contains(x, y))
                continue;

            Color c = bmp.GetPixel(x, y);
            if (c.R == 0 && c.G == 0 && c.B == 0)
            {
                Color cx;
                Color cy;
                int x_max;
                int y_max = bmp.Size.Height;
                int y2;

                for (x_max = x; x_max < bmp.Size.Width - 1; x_max++)
                {
                    for (y2 = y; y2 < bmp.Size.Height - 1; y2++)
                    {
                        cy = bmp.GetPixel(x_max, y2 + 1);
                        if (cy.R != 0 || cy.G != 0 || cy.B != 0)
                            break;
                    }
                    if (y2 < y_max)
                        y_max = y2;

                    cx = bmp.GetPixel(x_max + 1, y);
                    if (cx.R != 0 || cx.G != 0 || cx.B != 0)
                        break;
                }

                list.Add(new Rect(x, y, x_max, y_max));
            }
        }

        toolStripProgressBar1.Value++;
    }

    return list;
}

public class Rect
{
    public int Left { get; set; }
    public int Top { get; set; }
    public int Right { get; set; }
    public int Bottom { get; set; }
    public int X
    {
        get
        {
            return Left;
        }
    }
    public int Y
    {
        get
        {
            return Top;
        }
    }
    public int Width
    {
        get
        {
            int result = Right - Left + 1;
            return result;
        }
    }
    public int Height
    {
        get
        {
            int result = Bottom - Top + 1;
            return result;
        }
    }
    public Rect(int left, int top, int right, int bottom)
    {
        Left = left;
        Top = top;
        Right = right;
        Bottom= bottom;
    }
    public bool Contains(int x, int y)
    {
        bool result = Left <= x && x <= Right && Top <= y && y <= Bottom;
        return result;
    }
}

public class RectList : List<Rect>
{
    public bool Contains(int x, int y)
    {
        bool result = false;
        foreach (Rect rect in this)
        {
            result = rect.Contains(x, y);
            if (result)
                break;
        }
        return result;
    }
}

矩形はRectangleを使えばよいかもしれませんが、こっちの方が楽だったので。

ソースコード(Script-Fuのテンプレート)

(define (
    {スクリプト名}
    img
    drawable
    )

    ;Undoグループの開始
    (gimp-undo-push-group-start img)

    ;キャンバスサイズの変更
    (gimp-image-resize img {Width} {Height} -{X} -{Y})

    ;アルファチャンネルの追加
    (gimp-layer-add-alpha drawable)

    (gimp-rect-select img 0 0 0 0 REPLACE FALSE 0)

    ;範囲選択

    ;削除
    (gimp-edit-clear drawable)

    ;選択範囲の解除
    (gimp-selection-none img)

    ;undoグループの終了
    (gimp-undo-push-group-end img)

    ; 出力
    (gimp-displays-flush)
)

(script-fu-register
    "{スクリプト名}"
    "<Image>/Script-Fu/{コマンド名}"
    "{説明}"
    "R"
    "Copyright 2017, R"
    "May 28, 2017"
    ""
    SF-IMAGE "Image" 0
    SF-DRAWABLE "Drawable" 0
)

以上

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2