使用python-fu在GIMP中缩放图像,然后通过内置GUI进行缩放

时间:2015-01-21 10:48:58

标签: gimp python-fu

我在OS X上的GIMP 2.8.14中使用Python-Fu来自动化游戏的资产管道生产。

但是我注意到,当我从脚本执行它时,方法pdb.gimp_image_scale比较慢,与内置功能“Image> Scale Image ...”相比。

通过脚本将白图像从8000x8000缩小到2000x2000需要6.8秒,而GUI需要1.7秒。这不是那么重要,但是通过脚本缩小我的资产需要花费3分47秒,而GUI需要40秒。

我的Activity Monitor向我展示了我执行脚本时的CPU使用率仅高达约30%,其中内置GUI扩展使用高达100%,这意味着在OS X上单CPU核心的速度可以快到

有人有想法,我怎么能改变这种行为?

奇怪的是:这种接缝只是因为gimp_image_scale。其他操作如gimp_image_select_contiguous_color,gimp_selection_grow,gimp_selection_feather和gimp_edit_bucket_fill_full将CPU使用率提高到100%。

在Windows上它是相同的,但实际上并没有那么糟糕:通过脚本1分28秒,通过内置GUI 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()

UPDATE1: 我发现活动监视器具有“CPU历史记录”特征,在那里我看到我的假设是错误的:100%不是1核心,它分布在4核心上25%。

那么为什么两种情况下只有25%呢?为什么gimp_image_scale没有多线程?

通过GUI(左侧)与单线程通过脚本(右侧)进行多线程扩展

更新2: 当我从“过滤器&gt; Python-Fu&gt;控制台”运行我的脚本时,它实际上是多线程且快速的。

更新3: 当我运行我的脚本没有输入值(例如缩放)并硬编码该值时,它也运行多线程和快速。它接缝时,从对话框触发缩放时,它是单线程的。

2 个答案:

答案 0 :(得分:1)

我找到了一个hacky解决方法来从新线程执行gimp_image_scale。 而现在而不是3分37秒它只需要24秒,所以实际上比内置GUI解决方案更快,需要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()

答案 1 :(得分:1)

作为提示,这不会影响此问题,但应该帮助其他人执行几个(数百)像素级操作的脚本上的性能问题,例如画笔描边,或创建选择和填充:UNDO系统将所有内容拖下来即使在正确分组UNDO步骤时也是如此。

因此,密集脚本的提示是复制(pdb.gimp_image_duplicate)图像,调用 副本上的pdb.gimp_image_undo_disable,在那里执行操作,并在完成时pdb.gimp_edit_copypdb.gimp_edit_paste将相关的drawable传输到原始图像。