Скрипт Python-fu GIMP не вставляет изображение

Я пытаюсь написать скрипт, который нарезает слой на маленькие кусочки. Он работает правильно, но ничего не вставляется в новый слой.

def explode_layer( i, l, dx, dy ):
    T=[]
    for ix,ox in enumerate(range(l.offsets[0], l.offsets[0]+l.width, dx )):
        for iy,oy in enumerate(range(l.offsets[1], l.offsets[1]+l.height, dy)):
            pdb.gimp_rect_select(i, ox, oy, dx, dy, 2, False, 0)
            if not pdb.gimp_edit_copy(l):
                continue
            layer = pdb.gimp_layer_new(i, dx, dy, 1, 
                                       l.name+" %d,%d"%(ix,iy), 100, 0)
            i.add_layer(layer)
            floating_sel = pdb.gimp_edit_paste(layer, True)
            pdb.gimp_layer_set_offsets(floating_sel, *layer.offsets)
            pdb.gimp_floating_sel_anchor(floating_sel)
            T.append(layer)
    return T

Я использую gimp 2.6.8 на Ubuntu 10.04. Как я могу это исправить? Есть ли лучший подход?


person Arpegius    schedule 24.05.2012    source источник
comment
Помимо вашего основного вопроса, есть несколько проблем с вашим кодом, которые могут позже вызвать головную боль при обслуживании - некоторые из них могут быть огромными: Избегайте именования переменных с помощью одной буквы - особенно полноценные объекты, такие как i для изображения и l для слоя . Прежде всего - никогда не используйте одну букву l для имени переменной - ее слишком сложно отличить от 1, чтобы это было удобно. 2) Избегайте использования магических чисел - GIMP Python определяет константы, используйте их - поэтому использование CHANEL_OP_REPLACE вместо числа 2 - это способ сделать сценарий надежным в будущем.   -  person jsbueno    schedule 24.05.2012
comment
Спасибо за совет, я не собираюсь писать плагин, а просто использовать его в консоли python-fu. Если бы я разобрался со скриптами в gimp, я бы подумал о том, чтобы сделать его.   -  person Arpegius    schedule 24.05.2012
comment
ok - такие ярлыки подходят для однократного запуска окна консоли - однако этот код, однажды исправленный, уже является плагином - вам просто нужно написать для него вызов функции регистрации.   -  person jsbueno    schedule 24.05.2012


Ответы (1)


Сейчас я смотрю на ваш скрипт - это хороший подход - и я обнаружил, что не так: когда вы вызываете gimp_edit_paste, созданное вами выделение (с помощью gimp_rect_select) все еще активно, а содержимое вашего плавающего слоя обрезается. этим. (На самом деле я думаю, что они обрезаются только при вызове «selection_anchor», но это не имеет значения).

Таким образом, добавление строки pdb.gimp_selection_none(i) непосредственно перед floating_sel = pdb.gimp_edit_paste(layer, True) исправит вашу функцию:

def explode_layer( i, l, dx, dy ):
    T=[]
    for ix,ox in enumerate(range(l.offsets[0], l.offsets[0]+l.width, dx )):
        for iy,oy in enumerate(range(l.offsets[1], l.offsets[1]+l.height, dy)):
            pdb.gimp_rect_select(i, ox, oy, dx, dy, 2, False, 0)
            if not pdb.gimp_edit_copy(l):
                continue
            layer = pdb.gimp_layer_new(i, dx, dy, 1, 
                                       l.name+" %d,%d"%(ix,iy), 100, 0)
            i.add_layer(layer)
            pdb.gimp_selection_none(i)
            floating_sel = pdb.gimp_edit_paste(layer, True)
            pdb.gimp_layer_set_offsets(floating_sel, *layer.offsets)
            pdb.gimp_floating_sel_anchor(floating_sel)
            T.append(layer)
    return T

Более простой способ - не создавать новый слой явно (кстати, есть удобный, хотя и недокументированный метод "new_layer" для объекта изображения, который создает и добавляет новый слой и имеет разумные значения по умолчанию для большинства параметров - так что i.new_layer(<name>, <width>, <height>) будет достаточно) - но вы можете просто скопировать, вставить и вместо этого вызвать new_layer = pdb.gimp_floating_sel_to_layer(<floating_sel>).

person jsbueno    schedule 24.05.2012
comment
Есть ли метод gimp_floating_sel_*, который вставляется в новый слой? Я не нашел ни одного. - person Arpegius; 24.05.2012
comment
Спасибо работает хорошо. Я забываю, что вставка также использует выделение, и если я перемещу новый слой в плавающий, выделение будет прямо над новым слоем. В документации gimp_floating_sel_to_layer ничего не сказано о создании нового слоя, поэтому я просто пропустил это. - person Arpegius; 25.05.2012