使用 Kritarunner 自动化 Krita 脚本执行

偶尔想要使用 krita 自动化去做一些花活儿,比如批处理执行图像转换任务。

但一个麻烦的地方是,Krita 的 GUI 会被打开,这就很让人恼火。这也意味着你在绘画的时候就不能干花活儿。

实际上,Krita 提供了一个在后台运行的方案——kritarunner,它的原理是创建一个和原本的 krita 完全相同的环境,在后台使用这个环境去跑你的 python 脚本,并允许你在脚本中使用 Krita 内部 API

但这也导致这个程序其实也算是挺 expensive 的,尽量别轮询?

kritarunner 直接使用命令行调用(Win 下应当使用kritarunner.com),需要给定一个模块名和要执行的函数名(默认__main__)。还可给定其他参数, 剩下的参数都会以list[str]传递给这里要执行的函数。

形如:

1
$ kritarunner -s hello -f __main__ arg1 arg2 arg3

其中,hello.py这个模块,必须位于%APPDATA%\kritarunner\krita\pykrita下(对 Windows)!

更方便的方法?

kritarunner 这个限制有些蛋疼,我要是想要更加可插拔呢?

一个方法是做文件映射——单文件就直接映射,多文件我就把我的脚本都放到特定目录上去然后映射文件夹……

但这里可以整点花的——动态加载模块。

我们取第一个参数为要加载的模块(py 文件或目录),剩下的参数修改sys.argv(以模拟一般脚本命令行执行时的效果)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# %APPDATA%\kritarunner\krita\pykrita\exec.py

import sys
import os
from pathlib import Path

def import_external_module(module_path):
"""
导入外部 Python 模块

Args:
module_path: 外部模块的路径,可以是文件或目录
"""
module_path = Path(module_path).resolve()

if module_path.is_file():
# 如果是单个文件
module_dir = module_path.parent
module_name = module_path.stem
else:
# 如果是目录
module_dir = module_path
module_name = module_path.name

# 添加路径到 sys.path
if str(module_dir) not in sys.path:
sys.path.insert(0, str(module_dir))

# 导入模块
module = __import__(module_name)
return module

def __main__(args: list[str]):
if not args:
print('No script file given!')
return
module_path, *argv = args
sys.argv = argv
module = import_external_module(module_path)

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!