遍历嵌套的GIMP组以检索层阵列



我是python和编写GIMP插件的新手。我正在尝试编写一个简单的插件来执行层名称的搜索/替换。我已经设法使它与"平面"gimp图像一起工作,但不知道如何使它在组中迭代工作。这是我的"平面"结构代码:

import math
import string
import re
from gimpfu import *
from array import array
def python_search_replace_layer_names(image, layer, searchterm, replaceterm, applyvisible, casesensative) :
pdb.gimp_image_undo_group_start(image)
pdb.gimp_context_push() 
applylayers = []
for layer in image.layers[::-1]:
if (applyvisible == 0) or (layer.visible != 0): #user didn't check Only apply visible or if layer is visible.
applylayers.append([layer,counter])
for applylayer in applylayers:
if casesensative == 0:
searchtermRegEx = re.compile(re.escape(searchterm),re.IGNORECASE)
else:
searchtermRegEx = re.compile(re.escape(searchterm))     
layername = searchtermRegEx.sub(replaceterm, str(applylayer[0].name))
applylayer[0].name = layername  
pdb.gimp_context_pop()
pdb.gimp_image_undo_group_end(image)
pdb.gimp_displays_flush()
register(
"python_fu_search_replace_layer_names",
"Search/Replace in Layer Names",
"Search/Replace in Layer Names...",
"stigzler",
"stigzler",
"2020",
"<Image>/Edit/Search and Replace/Replace Layer Names...",
"RGB*, GRAY*", 
[
(PF_STRING, "searchterm", "Search for Term:", "SearchTerm"),
(PF_STRING, "replaceterm", "Replace With:", "ReplaceWith"),
(PF_TOGGLE, "applyvisible",   "Only Apply to visible layers:", 0),
(PF_TOGGLE, "casesensative",   "Case sensative:", 0)
],
[],
python_search_replace_layer_names)
main()

我猜这将涉及一些迭代的、自引用的函数,但我只掌握了三点知识:

  1. 相关插件结构操作
  2. 不知道python的语法/结构(通常是.net,尽管我确信有很多相似之处(
  3. 不知道访问组结构的gimpapi

希望有人能帮忙!


更新:

多亏了xenoid的回答,解决了这个问题。如果你在这里寻找一个层重命名插件,你可以在这里找到完成的

其实很简单。我写了一些代码来转储图像的层次结构:

def dump(parent,level,dumpList):
prefix='     '*level
for pos,layerOrGroup in enumerate(parent.layers):
dumpList.append(prefix+layerOrGroup.name)
if isinstance(layerOrGroup,gimp.GroupLayer):
dump(layerOrGroup,level+1,dumpList)
def dumpLayerHierarchy(image):
dumpList=[]
dump(image,0,dumpList)
gimp.message('n'.join(dumpList))

需要知道的两件事:

  • 层组是gimp.GroupLayer的实例(规则层是gimp.Layer(
  • 在最佳情况下,gimp.Imagegimp.GroupLayer都有layers属性中的子级,因此您甚至不需要对从图像本身开始的第一级进行特殊处理

PS:更好的注册:

register(
"search-replace-layer-names",
"Search/Replace in Layer Names",
"Search/Replace in Layer Names...",
"stigzler",
"stigzler",
"2020",
"Replace Layer Names...",
"*", 
[
(PF_IMAGE,"image", "Image:", None),
(PF_DRAWABLE, "drawable", "Drawable:", None),
(PF_STRING, "searchterm", "Search for Term:", "SearchTerm"),
(PF_STRING, "replaceterm", "Replace With:", "ReplaceWith"),
(PF_TOGGLE, "applyvisible",   "Only Apply to visible layers:", 0),
(PF_TOGGLE, "casesensative",   "Case sensative:", 0)
],
[],
python_search_replace_layer_names
menu="<Image>/Edit/Search and Replace/"
)

更改:

  • 化妆品:让"原子"更标准。Gimp添加的"python fu">
  • 将菜单声明更改为不推荐使用的类型,具有单独的菜单项和菜单位置
  • 使图像类型"*"支持所有图像类型(您的代码不适用于索引图像(
  • 明确"图像"one_answers"可绘制"参数。这有时很有用。由于您可能无论如何都不使用layer/drawable,因此可以将其从参数列表(以及从函数原型(中删除

其他:

  • 您不需要上下文推送/弹出,因为您不更改上下文
  • 你不需要复制图像层(image.layers[::-1](,甚至不需要反转它们,因为你只需要更新属性(如果你删除层,那就另当别论了(
  • 撤消组是好的,但您可以在try/except中将代码括起来,这样在出现问题时,撤消组将正确关闭,您仍然可以轻松地撤消部分更改:
import traceback # To still get source code location
def the_plugin(image,layer):
image.undo_group_start()
try:
# Your code goes here
except Exception as e:
trace(e.args[0])
gimp.message(e.args[0]+':'+traceback.format_exc())
image.undo_group_end()

您的代码,已修复:

import re,traceback
from gimpfu import *
def python_search_replace_layer_names(image,searchterm, replaceterm, applyvisible, casesensitive) :
image.undo_group_start()
try:
searchtermRegEx = re.compile(re.escape(searchterm),0 if casesensitive else re.IGNORECASE)
renameLayers(image,searchtermRegEx,replaceterm,applyvisible)  
except Exception as e:
gimp.message(e.args[0]+':'+traceback.format_exc())  
image.undo_group_end()
def renameLayers(parent,searchtermRegEx,replaceterm,applyvisible):
for pos,layerOrGroup in enumerate(parent.layers):
if not applyvisible or layerOrGroup.visible:
layerName = searchtermRegEx.sub(replaceterm, layerOrGroup.name)
layerOrGroup.name = layerName
if isinstance(layerOrGroup,gimp.GroupLayer):
renameLayers(layerOrGroup,searchtermRegEx,replaceterm,applyvisible)
register(
"search-replace-layer-names",
"Search/Replace in Layer Names",
"Search/Replace in Layer Names...",
"stigzler",
"stigzler",
"2020",
"Replace Layer Names...",
"*", 
[
(PF_IMAGE,"image", "Image:", None),
(PF_STRING, "searchterm", "Search for Term:", "SearchTerm"),
(PF_STRING, "replaceterm", "Replace With:", "ReplaceWith"),
(PF_TOGGLE, "applyvisible",   "Only Apply to visible layers:", 0),
(PF_TOGGLE, "casesensitive",   "Case sensative:", 0)
],
[],
python_search_replace_layer_names,
menu="<Image>/Edit/Search and Replace/")
main()

修复:

  • 在注册中的python_search_replace_layer_names末尾添加缺少的逗号
  • 已添加traceback导入
  • 删除了对trace函数的调用(仅在我自己的代码中(
  • 取消了许多不必要的进口
  • 已将layer参数删除到插件函数
  • level参数删除到递归函数
  • 一些代码变得更像蟒蛇

此外,组中的层可能是不可见的,因为它本身是不可见(layer.visible为false(,或者因为组是不可见。您当前的代码没有考虑组诱导的不可见性。

最后,可以在这里找到一些调试Gimp-python脚本的提示(重点是Windows(。

最新更新