Масштабирование изображения с помощью python-fu в GIMP медленнее, чем через встроенный графический интерфейс

Я использую Python-Fu внутри GIMP 2.8.14 на OS X, чтобы автоматизировать создание конвейера ресурсов для игры.

Но я заметил, что метод pdb.gimp_image_scale работает медленнее, когда я запускаю его из мой скрипт по сравнению со встроенной функцией «Изображение > Масштабировать изображение...».

Уменьшение белого изображения с 8000x8000 до 2000x2000 занимает 6,8 секунды с помощью сценария по сравнению с 1,7 секунды с помощью графического интерфейса. Это не так критично, но масштабирование моих активов с большим количеством слоев занимает 3 минуты 47 секунд по сценарию, по сравнению с 40 секундами с помощью графического интерфейса.

Мой монитор активности показал, что загрузка ЦП при выполнении моего скрипта достигает примерно 30 %, где встроенный графический интерфейс использует масштабирование до 100 %, что означает, что в OS X одно ядро ​​ЦП работает настолько быстро, насколько это возможно.

У кого-нибудь есть идея, как я могу изменить это поведение?

Странная вещь: похоже, это связано только с gimp_image_scale. Другие операции, такие как gimp_image_select_contiguous_color, gimp_selection_grow, gimp_selection_feather и gimp_edit_bucket_fill_full, увеличивают использование ЦП до 100%.

В Windows это то же самое, но на самом деле не так уж плохо: 1 минута 28 секунд через скрипт и 33 секунды через встроенный графический интерфейс.

from gimpfu import *

def scale_image(scale):
    image = gimp.image_list()[0]
    w = image.width
    h = image.height

    pdb.gimp_progress_init("Scaling Image...",None)
    pdb.gimp_context_set_interpolation(INTERPOLATION_LANCZOS)
    pdb.gimp_image_scale(image, w/scale, h/scale)
pass

register(
         "jeanluc_scale_image",
         "Scale Image",
         "Scale Image",
         "JeanLuc",
         "JeanLuc",
         "2015",
         "Scale Image...",
         "*",
         [
          (PF_INT, "scale", "Scale of Image", 1)
          ],
         [],
         scale_image,
         menu="<Image>/JeanLuc"
)

main()

ОБНОВЛЕНИЕ 1: я узнал, что в Activity Monitor есть функция «История ЦП», где я увидел, что мое предположение было неверным: 100% не на 1 ядре, а 25% распределены по 4 ядрам.

Так почему же в обоих случаях он работает только на 25% процентов? и почему gimp_image_scale не многопоточный?

Многопоточное масштабирование через графический интерфейс (слева) и однопоточное масштабирование через скрипт (справа)

ОБНОВЛЕНИЕ 2: когда я запускаю свой скрипт из консоли «Фильтры>Python-Fu>», он на самом деле является многопоточным и быстрым.

ОБНОВЛЕНИЕ 3: когда я запускаю свой скрипт без входного значения (например, масштаба) и жестко задаю значение, он также работает многопоточно и быстро. Похоже, что когда масштабирование запускается из диалогового окна, оно является однопоточным.


person JeanLuc    schedule 21.01.2015    source источник
comment
Интересно, может ли он использовать графический процессор при вызове через графический интерфейс?   -  person Mark Setchell    schedule 21.01.2015
comment
я попытался профилировать это, но потом обнаружил проблему на стороне ЦП, см. мой обновленный вопрос.   -  person JeanLuc    schedule 21.01.2015


Ответы (2)


Как подсказка, это не повлияет на эту проблему, но должно помочь другим с проблемами производительности в сценариях, которые выполняют несколько (сотни) операций на уровне пикселей, таких как обводка кистью или создание выделений и заливок: система UNDO перетаскивает все вниз, даже когда правильная группировка шагов UNDO.

Таким образом, подсказка для интенсивного сценария состоит в том, чтобы дублировать (pdb.gimp_image_duplicate) изображение, вызывать pdb.gimp_image_undo_disable для копии, выполнять там операции и, в конце, pdb.gimp_edit_copy и pdb.gimp_edit_paste для переноса соответствующих чертежей в исходное изображение.

person jsbueno    schedule 22.01.2015
comment
Спасибо за подсказку: поскольку моя система контроля версий может выполнять отмену/возврат, мне это не нужно в GIMP. Поэтому я просто деактивировал его. Производительность моего скрипта была увеличена с 2 минут 13 секунд до 1 минуты 51 секунды. - person JeanLuc; 22.01.2015

Я нашел хакерский обходной путь для выполнения gimp_image_scale из нового потока. И теперь вместо 3 минут и 37 секунд это занимает всего 24 секунды, что на самом деле быстрее, чем встроенное решение с графическим интерфейсом, которое занимает 40 секунд.

Если кто-то знает или найдет правильное решение, я приму это как ответ.

#!/usr/bin/env python

from threading import Thread
import time
from gimpfu import *

def scale_image(scale):
    pdb.gimp_progress_init("Scaling Image...",None)
    time.sleep(0.5)
    thread = Thread(target = thread_scale_image, args = (scale, ))
    thread.start()
    thread.join()
pass

def thread_scale_image(scale):
    image = gimp.image_list()[0]
    w = image.width
    h = image.height
    pdb.gimp_context_set_interpolation(INTERPOLATION_LANCZOS)
    pdb.gimp_image_scale(image, w/scale, h/scale)
pass

register(
         "jeanluc_scale_image",
         "Scale Image",
         "Scale Image",
         "JeanLuc",
         "JeanLuc",
         "2015",
         "Scale Image...",
         "RGB*",
         [
          (PF_INT, "scale", "Scale of Image", 4)
          ],
         [],
         scale_image,
         menu="<Image>/JeanLuc"
)

main()
person JeanLuc    schedule 22.01.2015
comment
Я думаю, что это более чем правильное решение для этого случая. Если бы у вас было время, вы могли бы отправить информацию, содержащуюся в этом вопросе, в GIMP bugzilla — это, возможно, помогло бы нам решить эту проблему в обозримом будущем. bugzilla.gnome.org/buglist.cgi?product=GIMP - person jsbueno; 22.01.2015
comment
Если вы чувствуете себя смелым, возможно, вы могли бы попробовать использовать привязки Python GEGL — я должен вернуться, чтобы взломать их в ближайшее время, но они обеспечивают прозрачный доступ Pythonic к большинству функций GEGL. GEGL, универсальная графическая библиотека, являющаяся кодом, фактически используемым в качестве механизма обработки изображений в текущих версиях GIMP. Недостатком является необходимость работать с API, полностью отличным от того, который доступен в GIMP. Преимущество заключается в том, что вы не удивляетесь проблемам с производительностью из-за пользовательского интерфейса. вопросы. - person jsbueno; 22.01.2015
comment
спасибо, я хотя бы отправлю отчет об ошибке. Я мог бы взглянуть на Python GEGL в будущем, когда мне понадобится больше контроля над GIMP или я столкнусь с другим падением производительности. - person JeanLuc; 22.01.2015
comment
Да, конечно, я забыл упомянуть, но если вы не манипулируете изображением в интерактивном режиме, всегда имеет смысл отключить отмену. - person jsbueno; 22.01.2015
comment
Главный бузкилл: GNOME Bugzilla покажет мою электронную почту всем. Извините, но нет, спасибо, я предпочитаю, чтобы даже моя третья электронная почта была конфиденциальной. - person JeanLuc; 22.01.2015