GIMP 一键均匀添加多条参考线 一键均匀切分图片

添加参考线

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from gimpfu import *

# orientation: ORIENTATION_HORIZONTAL(0), ORIENTATION_VERTICAL(1)
# diff: 参考线之间的间隔
def add_multi_guides(img, drawable, orientation, diff):
    # img = gimp.image_list()[0]
    # uri = img.uri
    w, h = img.width, img.height
    endposition = None
    add_guide = None

    if orientation == ORIENTATION_HORIZONTAL:
        assert diff < h, 'diff too big'
        endposition = h
        add_guide = pdb.gimp_image_add_hguide
    elif orientation == ORIENTATION_VERTICAL:
        assert diff < w, 'diff too big'
        endposition = w
        add_guide = pdb.gimp_image_add_vguide
    else:
        raise ValueError(('orientation not valid: {0}').format(orientation))

    # 清空原来的参考线
    guide = pdb.gimp_image_find_next_guide(img, 0)
    while guide != 0:
        if orientation == pdb.gimp_image_get_guide_orientation(img, guide):
            pdb.gimp_image_delete_guide(img, guide)
            guide = 0
        guide = pdb.gimp_image_find_next_guide(img, guide)

    position = diff
    while position < endposition:
        add_guide(img, position)
        position = position + diff

register(
    "add_multi_guides",
    # table snippet means a small piece of HTML code here
    "Add fucking guides",
    "long description",
    "hangj",
    "hangj",
    "2020",
    "Add Multi Guides...",
    "*",
    [
        (PF_IMAGE, "img", "Input image", None),
        (PF_DRAWABLE, "drawable", "Input drawable", None),
        (PF_OPTION, "orientation", "orientation", 0, ("HORIZONTAL", "VERTICAL")),
        (PF_INT, "diff", "pixcels between guides", 1000)
    ],
    [],
    add_multi_guides,
    menu="<Image>/Image/Guides"
    )

main()

一键切分图片

一键切分的代码是把我上面添加参考线的代码与 GIMP 内 py-slice.py 合并在一起的。
其实更优的做法是直接复制一份 py-slice.py 换个文件名,然后修改 get_guides 函数(通过用户给的参数直接生成参考线坐标,而不需要真的添加参考线然后再读取参考线的坐标)

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import os

from gimpfu import *
import os.path

gettext.install("gimp20-python", gimp.locale_directory, unicode=True)

# orientation: ORIENTATION_HORIZONTAL(0), ORIENTATION_VERTICAL(1)
# diff: 参考线之间的间隔
def add_multi_guides(img, orientation, diff):
    w, h = img.width, img.height
    endposition = None
    add_guide = None

    if orientation == ORIENTATION_HORIZONTAL:
        assert diff < h, 'diff too big'
        endposition = h
        add_guide = pdb.gimp_image_add_hguide
    elif orientation == ORIENTATION_VERTICAL:
        assert diff < w, 'diff too big'
        endposition = w
        add_guide = pdb.gimp_image_add_vguide
    else:
        raise ValueError(('orientation not valid: {0}').format(orientation))

    # 清空原来的参考线
    guide = pdb.gimp_image_find_next_guide(img, 0)
    while guide != 0:
        if orientation == pdb.gimp_image_get_guide_orientation(img, guide):
            pdb.gimp_image_delete_guide(img, guide)
            guide = 0
        guide = pdb.gimp_image_find_next_guide(img, guide)

    position = diff
    while position < endposition:
        add_guide(img, position)
        position = position + diff


def pyslice(image, drawable, orientation, diff, save_path,
            image_basename, image_extension,
            image_path):

    add_multi_guides(image, orientation, diff)

    vert, horz = get_guides(image)

    if len(vert) == 0 and len(horz) == 0:
        return

    gimp.progress_init(_("Equally Slice"))
    progress_increment = 1 / ((len(horz) + 1) * (len(vert) + 1))
    progress = 0.0

    def check_path(path):
        path = os.path.abspath(path)

        if not os.path.exists(path):
            os.mkdir(path)

        return path

    save_path = check_path(save_path)

    if not os.path.isdir(save_path):
        save_path = os.path.dirname(save_path)

    image_relative_path = ''
    image_path = save_path

    top = 0

    for i in range(0, len(horz) + 1):
        if i == len(horz):
            bottom = image.height
        else:
            bottom = image.get_guide_position(horz[i])

        left = 0

        for j in range(0, len(vert) + 1):
            if j == len(vert):
                right = image.width
            else:
                right = image.get_guide_position(vert[j])
            if (
                   (len(horz) >= 2 and (i == 0 or i == len(horz) )) or
                   (len(vert) >= 2 and (j == 0 or j == len(vert) ))
               ):
                skip_stub = True
            else:
                skip_stub = False

            slice (image, None, image_path,
                  image_basename, image_extension,
                  left, right, top, bottom, i, j, "")

            left = right

            progress += progress_increment
            gimp.progress_update(progress)

        top = bottom

def slice(image, drawable, image_path, image_basename, image_extension,
          left, right, top, bottom, i, j, postfix):
    if postfix:
        postfix = "_" + postfix
    src = "%s_%d_%d%s.%s" % (image_basename, i, j, postfix, image_extension)
    filename = os.path.join(image_path, src)

    if not drawable:
        temp_image = image.duplicate()
        temp_drawable = temp_image.active_layer
    else:
        if image.base_type == INDEXED:
            #gimp_layer_new_from_drawable doesn't work for indexed images.
            #(no colormap on new images)
            original_active = image.active_layer
            image.active_layer = drawable
            temp_image = image.duplicate()
            temp_drawable = temp_image.active_layer
            image.active_layer = original_active
            temp_image.disable_undo()
            #remove all layers but the intended one
            while len (temp_image.layers) > 1:
                if temp_image.layers[0] != temp_drawable:
                    pdb.gimp_image_remove_layer (temp_image, temp_image.layers[0])
                else:
                    pdb.gimp_image_remove_layer (temp_image, temp_image.layers[1])
        else:
            temp_image = pdb.gimp_image_new (drawable.width, drawable.height,
                                         image.base_type)
            temp_drawable = pdb.gimp_layer_new_from_drawable (drawable, temp_image)
            temp_image.insert_layer (temp_drawable)

    temp_image.disable_undo()
    temp_image.crop(right - left, bottom - top, left, top)
    if image_extension == "gif" and image.base_type == RGB:
        pdb.gimp_image_convert_indexed (temp_image, CONVERT_DITHER_NONE,
                                        CONVERT_PALETTE_GENERATE, 255,
                                        True, False, False)
    if image_extension == "jpg" and image.base_type == INDEXED:
        pdb.gimp_image_convert_rgb (temp_image)

    pdb.gimp_file_save(temp_image, temp_drawable, filename, filename)

    gimp.delete(temp_image)
    return src

class GuideIter:
    def __init__(self, image):
        self.image = image
        self.guide = 0

    def __iter__(self):
        return iter(self.next_guide, 0)

    def next_guide(self):
        self.guide = self.image.find_next_guide(self.guide)
        return self.guide

def get_guides(image):
    vguides = []
    hguides = []

    for guide in GuideIter(image):
        orientation = image.get_guide_orientation(guide)

        guide_position = image.get_guide_position(guide)

        if guide_position > 0:
            if orientation == ORIENTATION_VERTICAL:
                if guide_position < image.
                    vguides.append((guide_position, guide))
            elif orientation == ORIENTATION_HORIZONTAL:
                if guide_position < image.height:
                    hguides.append((guide_position, guide))

    def position_sort(x, y):
        return cmp(x[0], y[0])

    vguides.sort(position_sort)
    hguides.sort(position_sort)

    vguides = [g[1] for g in vguides]
    hguides = [g[1] for g in hguides]

    return vguides, hguides

register(
    "equally-slice",
    N_("Cuts an image equally, creates images"),
    """Cuts an image equally, creates images""",
    "hangj",
    "hangj",
    "2020",
    _("_Equally Slice..."),
    "*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "drawable", "Input drawable", None),
        (PF_OPTION, "orientation", "orientation", 0, ("HORIZONTAL", "VERTICAL")),
        (PF_INT, "diff", "pixcels every piece", 1000),
        (PF_DIRNAME, "save-path",     _("Path for images"), os.getcwd()),
        (PF_STRING, "image-basename", _("Image name prefix"),    "equallyslice"),
        (PF_RADIO, "image-extension", _("Image format"),         "jpg", (("gif", "gif"), ("jpg", "jpg"), ("png", "png"))),
        (PF_STRING, "relative-image-path", _("Folder for image export"), "images"),
    ],
    [],
    pyslice,
    menu="<Image>/Filters/Web",
    domain=("gimp20-python", gimp.locale_directory)
    )

main()

把脚本保存,放到 plug-ins 目录下,然后chmod +x filename,重启 GIMP,设置快捷键

plug-ins 目录在哪?


快捷键怎么设置?


输入 equally 找到我们的脚本

然后自行设置

原文地址:https://www.cnblogs.com/hangj/p/13338502.html