使用script-fu-drop-shadow时触发gimp-image-set-active-layer无效ID错误
问题:GIMP Script-Fu批量添加投影报错"无效图层ID"
背景
我希望不通过GIMP界面为图片文件添加投影,编写了以下Script-Fu脚本并保存至~/.config/GIMP/2.10/scripts/my.scm:
(define (my/add-drop-shadow filename) (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (drawable (car (gimp-image-get-active-layer image)))) ;; 应用投影效果 (script-fu-drop-shadow RUN-NONINTERACTIVE image drawable 20.0 20.0 10.0 0 0.5 nil)))
(注:目前代码未添加保存图片的逻辑,计划功能正常后补充)
运行报错
执行命令及错误输出如下:
$ gimp --version 2.10.30 $ gimp -i -b '(my/add-drop-shadow "2022-11-01-080429.png")' -b '(gimp-quit 0)' GIMP-Error: Calling error for procedure 'gimp-image-set-active-layer': Procedure 'gimp-image-set-active-layer' has been called with an invalid ID for argument 'active-layer'. Most likely a plug-in is trying to work on a layer that doesn't exist any longer. batch command experienced an execution error: Error: Procedure execution of gimp-image-set-active-layer failed on invalid input arguments: Procedure 'gimp-image-set-active-layer' has been called with an invalid ID for argument 'active-layer'. Most likely a plug-in is trying to work on a layer that doesn't exist any longer. /home/cassou/.nix-profile/bin/gimp: GEGL-WARNING: (../gegl/buffer/gegl-tile-handler-cache.c:1076):gegl_tile_cache_destroy: runtime check failed: (g_queue_is_empty (&cache_queue)) EEEEeEeek! 2 GeglBuffers leaked
请问是代码编写有误,还是插件存在问题?
调试信息更新
在脚本的let代码块开头添加打印语句:
(print "=============================") (print image) (print drawable) (print "=============================")
得到输出:
"=============================" 1 2 "============================="
问题原因及修复方案
问题出在script-fu-drop-shadow的调用逻辑上:这个内置脚本是为GIMP交互模式设计的,内部会依赖交互环境的图层状态(比如尝试修改活动图层),直接在非交互模式下调用会导致图层上下文不匹配,触发"无效图层ID"错误。
正确的做法是绕过这个封装脚本,直接调用GIMP底层API来手动实现投影效果。修改后的完整脚本如下:
(define (my/add-drop-shadow filename) (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (drawable (car (gimp-image-get-active-layer image))) ;; 从原图层复制生成投影图层 (shadow-layer (car (gimp-layer-new-from-drawable drawable image)))) ;; 设置投影图层名称 (gimp-item-set-name shadow-layer "Drop Shadow") ;; 将投影图层插入到原图层下方 (gimp-image-insert-layer image shadow-layer 0 1) ;; 对投影图层应用高斯模糊(模糊半径10px) (plug-in-gauss-rle RUN-NONINTERACTIVE image shadow-layer 10.0 10.0 0) ;; 偏移投影位置(右移20px,下移20px) (gimp-layer-translate shadow-layer 20 20) ;; 设置投影透明度为50% (gimp-layer-set-opacity shadow-layer 50.0) ;; 保存修改后的图片 (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename) ;; 删除图片对象,避免资源泄漏 (gimp-image-delete image)))
关键修复点说明:
- 用
gimp-layer-new-from-drawable直接复制原图层作为投影基底,避免依赖交互脚本的图层创建逻辑 - 通过
gimp-image-insert-layer调整图层顺序,确保投影在原图层下方 - 用
plug-in-gauss-rle实现模糊效果,对应原脚本中的模糊半径参数 gimp-layer-translate实现投影偏移,匹配原脚本的20x20偏移量gimp-layer-set-opacity设置投影透明度,对应原脚本的0.5参数- 添加
gimp-image-delete清理资源,解决GEGL缓冲区泄漏警告 - 补全了图片保存逻辑,完成完整的处理流程
修改后重新运行脚本即可正常生成带投影的图片,不会再出现图层相关错误。
内容的提问来源于stack exchange,提问作者Damien Cassou
相关产品推荐
相关产品推荐

