Gimp:将每个图层导出为单独的PNG图像

我遇到了一个情况,我在Gimp中有一张带有多个图层的图片。现在,我想自动将每个图层导出为单独的图片(最好是PNG格式),并保存到某个文件夹中。
这种操作是否可行?
长方法:隐藏除一个之外的所有图层,裁剪所需部分,导出图片。保存图层后,取消隐藏另一个图层,再次裁剪所需部分,导出。重复此过程。对于包含大约20个图层的图片来说,这样做有点麻烦。

Parto,请考虑接受@ThorSummoner的答案https://askubuntu.com/a/749561/453746,因为对于今天找到这个答案的新人来说,这似乎是一个更好的解决方案,而无需安装插件。 - Jeff Puckett
11个回答

如果PNG是可接受的输出格式,一种选择是将其导出为Open Raster(.ora),这是一种用于分层图像文件的开放规范。
  1. 将图像导出为Open Raster格式(.ora)

    文件 -> 另存为...

    myfile.ora

  2. 使用类似于file-roller7zip的程序,将myfile.ora打开为一个存档文件。

    在Ubuntu上:

    $ file-roller myfile.ora
    
    $ # 注意,Ubuntu上的较新版本的file-roller硬编码了文件后缀,
      # 并拒绝打开“.ora”文件,通过将文件重命名为“.zip”来解决此问题
    $ ln -s myfile.ora myfile.ora.zip
    $ file-roller myfile.ora.zip
    

    或者

    $ unzip myfile.ora
    

    所有图层都将作为PNG图像位于/data目录下,提取它们并随意使用。


13太棒了,谢谢!我认为这是最好的解决方案。无需安装,速度非常快。我刚刚用GIMP和PSD完成了它。 - LowFieldTheory
1这给我导出了一个扁平化的图像 :( - Petah
做得非常好!谢谢。在Gimp 2.8.20中运行良好。 - VIK
太棒了!你救了我的一天。 - GhitaB
非常好。请注意,编号从顶层开始,而其他一些技术则从底层开始。 - Deleplace
(+1)很酷的回答! - clickbait
14看起来2.10版本中不再支持ORA。:( - spacer GIF
@spacerGIF 你能引用一下移除的地方吗?你确定你没有混淆保存和导出的概念吧? - ThorSummoner
@ThorSummoner 在网上找不到任何关于这个的参考资料,但在2.8中我使用过这种技术,而在2.10中我不再能够使用。是的,我在导出菜单中,而不是保存。 - spacer GIF
2我对这个的唯一问题是它不使用我的图层名称作为文件名,这意味着我必须手动映射它们。 - Michael
1@michael 哎呀,我猜元数据应该在ora文件里面,也许可以很容易地编写一个脚本来处理。但是就这样说,我不确定为什么或者需要什么才能编写一个GIMP导出扩展程序以便第一时间做正确的事情。 - ThorSummoner
1我注意到最近的Ubuntu发行版中,文件管理器可能无法正常打开ora文件。如果这给您带来了困扰,可以尝试在文件名末尾添加“.zip”,这样可能会使您所使用的解压工具能够成功提取文件。 - ThorSummoner
1另一个问题是图像尺寸现在受限于图层尺寸。例如,如果你有一个带有透明边界的图层,那么导出的图层图像会比图像本身要小。 - Saren Tasciyan
@Genom 不错的建议,作为一种解决方法,将每个图层调整大小以匹配图像尺寸在这种情况下有帮助吗? - ThorSummoner
5дёҚд»…еңЁ2.10.20зүҲжң¬дёӯд»Қ然йқһеёёеҘҪз”ЁпјҢиҖҢдё”еӯҳжЎЈдёӯз”ҡиҮіжңүдёҖдёӘstack.xmlж–Ү件пјҢе…¶дёӯеҢ…еҗ«дәҶжүҖжңүзҡ„еӣҫеұӮеҸӮж•°гҖӮдҪҝз”Ёsedз®ЎйҒ“еҸҜд»Ҙеҝ«йҖҹеҲӣе»әдёҖз»„е‘Ҫд»ӨжқҘжҒўеӨҚеҺҹе§Ӣзҡ„еӣҫеұӮеҗҚз§°пјҡcat stack.xml | sed -e 's/><layer/\n/g;' | sed -E -e 's/.*name="([^"]*)".*src="([^"]*)".*/cp "\2" "\1"/;' - FeRD
实际上,当GIMP导出ORA文件时,你甚至可以“看到”它将所有图层转储到一个临时目录中作为单独的PNG文件,然后再将它们全部压缩起来。如果我们能在这个导出过程中提前停止一步,我们就已经完成了。 - FeRD
2原来,ORA文件的导出器是用Python编写的。请参阅我的回答,了解为什么这很重要。 - FeRD
2ORA导出在2.10.26版本中完美运行(至少在Windows系统上)。虽然速度很慢,但它能正常工作。https://gitlab.gnome.org/search?group_id=8&nav_source=navbar&project_id=1848&repository_ref=master&scope=&search=openraster&search_code=true&snippets=false - rautamiekka

你也可以尝试一下这个插件,导出图层。我已经用png格式测试过了,它可以正常工作。你只需要选择文件夹和格式,就能将所有图层分别保存在各自的文件中。

2这是最简单的。提取文件,将.py文件复制到您的~/.gimp-2.8/plug-ins文件夹中,使其可执行,重新启动GIMP。 - Parto
顺便说一下,在GIMP 2.6中不起作用。 - installero
3这也可以在GitHub上找到:https://github.com/khalim19/gimp-plugin-export-layers - moi
这个插件的安装说明太蠢了。:P 请直接安装,我不在意目录。 - ether_joe
同意安装(适用于Linux)比较困难;这是我需要使用的命令,以使其与AppImage GIMP安装配合工作: ./export_layers-3.2.1-linux.run --target /home/myname/.config/GIMP-AppImage/2.10/plug-ins/ -- -g /path/to/gimp-git-2.10.5-20180719.glibc2.15-x86_64.AppImage -i /home/myname/.config/GIMP-AppImage/2.10/plug-ins/ - user272901

首先,您不需要任何插件。甚至不需要裁剪任何东西。只需几个简单的步骤。
1. 选择一个图层。只需点击该特定图层即可。 2. 使用 Ctrl+C 将图层复制到剪贴板上。 3. 现在使用 Ctrl+Shift+V 创建新图像。 就是这样。现在您可以将该图层导出为任何格式。
4. 使用 Shift+Ctrl+E。

如果你只想要特定的图层,那么这是更好的选择... - Murshid Ahmed
7另外,如果你只想要两层或三层的话,那就不太好了。如果你发现自己(就像我昨天一样)想要导出动态GIF中的每一帧,这就不太理想了。 - FeRD
1这并不回答问题“我想要将每一个图层作为单独的图像(最好是PNG格式)自动地导出”,因为这种方法并不是自动化的。 - brunetton
继上一条评论之后,如果你仍然想要这样做,有一个比复制和粘贴图层更简单的方法:隐藏除了你想要保存的那个图层之外的所有图层,取消隐藏下一个图层并保存,然后重复这个步骤。 - undefined

可以将图像导出为动画GIF。这样每个图层都会保存为GIF中的一个单独帧。
然后,使用ImageMagick命令convert -coalesce ./myfile.gif outfile%05d.png将帧提取为PNG图像。

7注意:GIF仅支持256色调色板,因此无法以这种方式使用24位PNG。 - thomasrutter
2此外,对于大型图像来说,使用convert命令需要花费很长时间,而解压缩ORA文件几乎是瞬间完成的。不过,这个想法不错。 - Skippy le Grand Gourou


工作得非常好!谢谢! - deepthought-64
看起来在Bash 5.1.16中for i in {0..42}; do magick layeredImage.xcf["${i}"] "${i}.png"; done似乎可以正常工作。 - Sebastian Simon

当然,这个插件适用于导出图层到文件
功能:
- 操作图层组中的图层。 - 导出文本、图案和图层滤镜。 - 必须提供图像文件的前缀名称。 - 仅支持jpgpngbmp格式的导出,但可以轻松地添加所需的格式。

2链接已失效,但搜索插件名称可以找到:https://khalim19.github.io/gimp-plugin-export-layers/这是你所指的插件吗? - Job
请使用提供的链接申请工作。 - Akshay Vijay Jain

ThorSummoner的回答最好的地方在于它提到了OpenRaster导出插件,而这个插件实际上位于GIMP安装目录下的file-openraster.py文件中。
通过阅读它的代码(并在内置的过程浏览器的帮助下),我能够确定GIMP XCF的图层可以通过在界面中转到Filters > Python-fu > Console,并将以下内容输入到内置的Python解释器中来保存为单独的PNG文件:
import os

# If you have multiple images open, you may need to adjust
img = gimp.image_list()[0]

savefn = gimp.pdb['file-png-save-defaults']
outpath = "/home/$USER/Pictures" # (or r"C:\Users\$USER\Pictures", etc)

for lay in img.layers:
    # Even if your layer names contain spaces, not a problem
    outname = lay.name + ".png"
    savefn(img, lay, os.path.join(outpath, outname), outname)
    
    # type an extra newline to exit the indented block

在图像窗口的状态栏中,你会看到进度条开始快速地遍历所有图层,并将每个图层写入一个同名的PNG文件中,保存在你指定的目录下(该目录必须已经存在,否则在循环之前添加os.makedirs(outpath, exist_ok=True))。

如果你的图层名称相同,那就有问题了,因为它会毫不犹豫地覆盖任何先前写入的文件。注意GIMPtor。

编辑:如果你确实有同名的图层,你可以简单地忽略名称,而是将图层写入以数字命名的文件中。只需用以下内容替换上面的最后一个循环:

for n, lay in enumerate(img.layers):
    outname = f"Layer {n:03}.png"
    savefn(img, lay, os.path.join(outpath, outname), outname)

这将把图层写入名为“Layer 000.png”到“Layer 999.png”的PNG文件中(如果图层数少于1000,则写入相应数量的文件)。

如果Gimp的Python版本不支持f-strings(Python 3.6+),则以下代码完全等效:

outname = "Layer {0:03}.png".format(n)

1太搞笑了,谢谢!在Windows上,我必须像这样添加一个目标路径,否则它会尝试写入c:\windows\system32: savefn(img, lay, 'c:\\temp\\'+outname, outname) - ernstkl
1@ernstkl 啊,是的,那可能有道理。我会加入一个完整路径的示例,因为以图形方式启动肯定比像我这样从终端运行gimp更常见。(实际上,你可以使用原始字符串(r"C:\temp\")或者"C:/temp/"+outname来写入该路径,因为Python在Windows上已经支持分隔符转换了一段时间了。"最正确"的规范形式可能是os.path.join("C:", r"\temp", outname),但那太丑陋了。而且当路径直接输入时,而不是存储在变量中时,这种方式也没有什么意义。) - FeRD

多年以后,GIMP从被接受的解决方案中删除了这个功能,而其他一些代码解决方案也已经遭受了代码腐败(我无法在Python3中运行GIMP导出器)。
由于这是在Google搜索如何将GIMP图层导出为自己的PNG文件时的第一个搜索结果,所以我觉得有责任提供一个更新的答案。
我正在使用GIMP 2.10.18。
以下是一个对我有效的解决方案:
  • XCF文件导出为PDF文件 -> 导出为),请注意以下事项:
    • 确保选择图层作为页面(从底部图层开始)
    • 确保取消选择保存前应用图层蒙版
    • 确保取消选择尽可能将位图转换为矢量图形
    • 确保取消选择省略隐藏图层和不透明度为零的图层
  • 使用命令行工具pdftoppm导出为PNG文件。

例如,如果您要将XCF文件导出为文件exported_layers.pdf,则以下操作将创建每个图层作为单独的PNG图像,并以前缀out_命名(例如out_01.pngout_02.png等):

pdftoppm -png -r 300 exported_layers.pdf out_

-r选项是分辨率,据推测应该与导出为PDF文件时GIMP的默认设置相匹配。我发现300可以保持我的原始XCF文件中图层的分辨率,但实际情况可能有所不同。

在Ubuntu上,可以通过以下命令安装pdftoppm

apt-get install poppler-utils

1不错,唯一的缺点是透明度没有保留。如果你不需要透明度,这是一个不错且简单的方法。 - devklick

我也在做同样的事情,试图下载答案中提到的插件。由于Gimp网站目前无法访问,我无法获取这些插件,只能找到另一个解决方案。
我最终使用了截屏软件Shutter,它允许你选择屏幕的某个区域,然后你可以通过点击一次重复截取该区域的屏幕截图。 这样每个图层操作只需要两次点击:隐藏图层,截屏,隐藏下一个图层,截屏...
比其他任何方法都要快得多,对于20个图层只需不到一分钟的时间。虽然可能会损失图像质量,但在我的情况下并不是问题。

作为对我之前基于脚本的建议的另一种方法,我最终发现如果你安装了GIMP GAP,你也可以用其中的一个工具来实现这个功能。(那是Gimp动画...包?插件?类似那样的东西。)
在GAP菜单选项的“视频”菜单中,有一个“将图像拆分为帧…”的选项,它会将每个图层保存为单独的文件。以您指定的格式(通过文件扩展名),并且提供了几种处理图层的选项。下面是当我选择该选项后,保存了一个未经优化的动画GIF作为一个由52个图层组成的/tmp/testfile.xcf文件时弹出的对话框。

Split Image into Frames dialog window

尽管文件名预览显示,帧被保存为/tmp/testfile_01.png/tmp/testfile_52.png,如所指定的那样。(它不会根据您的选择更新显示的字符串,但会遵守您的选择。)