Krita Python 脚本编程入门

在 4.0 版本加入.

我们曾经在 Kickstarter 筹款活动中把 Python 脚本、矢量图形、文字工具三者作为候选延伸目标,结果 Python 脚本以压倒性的优势赢得了支持者投票。不少人甚至只给 Python 功能投了票。那么 Python 脚本编程究竟是何方神圣呢?

Python 脚本简介

Python 是一种脚本语言,可以用来编写一些自动化任务。对 Krita 来说,支持 Python 编程意味着我们为 Krita 打造了一个 API (编程接口),让 Python 脚本可以访问 Krita 的各项功能,这样我们便可以用 Python 脚本来打造工具面板、执行低级而量大的重复性文件操作,甚至制作定制化的导出功能。在计算机图形业界,如特效、游戏行业的从业人员可以借助 Python 编程来组织拼合图、自动化一些导出操作等,提高工作效率。

Python 编程教学并非本使用手册的内容范畴。考虑到 Python 是一种既流行又好学的编程语言,找到学习它的资源想必不会是一件难事。随便在网上搜索“Python 入门”估计就能得到无数结果。

本手册会把注意力放在如何使用 Python 为 Krita 进行自动化和扩展功能上面。现在,让我们学习基础中的基础:如何在脚本工具里面执行 Python 指令。

如何启用脚本工具插件

你并不是非得通过脚本工具插件才能在 Krita 里面执行 Python 脚本,但它在调试 Python 脚本时非常好用。它是一个用 Python 编写的 Python 脚本控制台,你可以在它里面直接编写和执行脚本片段。

要打开脚本工具插件,在菜单栏点击 工具 ‣ 脚本 ‣ 脚本工具 。如果看不到该工具,在菜单栏点击 设置 ‣ 配置 Krita ‣ Python 插件管理器 ,在对话框中勾选“脚本工具”。如果连那里也看不到该插件,请确保你使用的是最新正式版的 Krita。

脚本工具对话框的上半部分是一个文本编辑器,下半部分是一个输出信息的显示框。在文本编辑器中输入下面的代码:

print("hello world")

要执行脚本,可以点击对话框左上角的“播放”按钮,也可以按 Ctrl + R 快捷键。现在输出框中应该会显示:

==== Warning: Script not saved! ====
hello world

现在我们知道这个控制台可以执行 Python 环境中的 print() 这样的功能了,那么我们应该如何使用它来对 Krita 进行操作呢?

执行 Krita 的基本命令

要让 Python 和 Krita 建立联系,我们需要使用 Krita 模块。在脚本的起始处插入 from krita import *

这行代码让我们可以通过 Krita.instance() 接口与 Krita 建立联系。现在我们可以用 Python 执行 Krita 的操作了。

from krita import *

Krita.instance().action('python_scripter').trigger()

上述代码执行后会打开另一个脚本工具窗口。是不是很有意思?接下来让我们尝试一组更加复杂的代码。

from krita import *

d = Krita.instance().createDocument(512, 512, "Python test document", "RGBA", "U8", "", 120.0)
Krita.instance().activeWindow().addView(d)

这段代码会新建一个具有指定参数的文档。不难想象,使用 Python 脚本可以控制 Krita 进行许多自动化操作。假以时日,我们相信 Krita 社区会写出各种各样的脚本,到时候你只需要把代码复制到脚本工具里面执行即可。

可要是你想自己编写一些新命令,该怎么学习呢?最好的办法当然是:看看别人是怎么写的!使用别人的已有代码作为基础可以节省许多时间。你可以参考 /share/krita/pykrita 目录里预装的 Python 插件。我们还在用户手册里准备了 Krita Python 插件编写教程

不过仅凭这些还远远不够。要发现 import * from Krita 的星号位置还可以填入什么其他的 Krita 功能,学习它们的用法,可以阅读 Krita API 参考文档。

Krita 的 API

这两个页面可能看起来非常艰深。这很难避免,毕竟 Krita 是通过 C++ 编程语言编写的。Python 脚本在与 Krita 建立联系时会通过 SIP 使用 C++,这样当我们使用 import krita 来调用功能时,我们实际上调用的是这些文档里列举的 C++ 功能。

让我们仔细观察一下这些功能是如何工作的。在 Krita 程序类参考文档 页面列出了 Krita 进程的所有可用功能。如果你在 Python 里输入 dir(Krita.instance()) ,它返回的结果应该和该页非常相近。你可以研究一下前面例子使用过的功能:createDocument()activeWindow()action()

看到 Krita 的各种 C++ 程序类和 Q 开头的 Qt 程序类混列在一起会让人觉得眼花缭乱。不过这正是 SIP 大展身手的地方:它会尽可能把这些程序类翻译为简单易懂的 Python 格式。例如你可以看到 filters() 函数返回一个 QStringList ,而 SIP 会把那些 QStringList 转换成正常的 Python 字符串。

from krita import *

print(Krita.instance().filters())

输出为:

['asc-cdl', 'autocontrast', 'blur', 'burn', 'colorbalance', 'colortoalpha', 'colortransfer',
'desaturate', 'dodge', 'edge detection', 'emboss', 'emboss all directions', 'emboss horizontal and vertical',
'emboss horizontal only', 'emboss laplascian', 'emboss vertical only', 'gaussian blur', 'gaussiannoisereducer',
'gradientmap', 'halftone', 'height to normal', 'hsvadjustment', 'indexcolors', 'invert', 'lens blur', 'levels',
'maximize', 'mean removal', 'minimize', 'motion blur', 'noise', 'normalize', 'oilpaint', 'perchannel', 'phongbumpmap',
'pixelize', 'posterize', 'raindrops', 'randompick', 'roundcorners', 'sharpen', 'smalltiles', 'threshold', 'unsharp',
'wave', 'waveletnoisereducer']

不过有时候这种转换也会遇到一些问题。例如:

from krita import *

print(Krita.instance().documents())

返回的是:

[<PyKrita.krita.Document object at 0x7f7294630b88>,
<PyKrita.krita.Document object at 0x7f72946309d8>,
<PyKrita.krita.Document object at 0x7f7294630c18>]

它列出了一坨不知道是什么玩意,这下怎么办?我们可以回头参考一下 Krita API 文档页面,看看 documents() 是怎么回事。你会看到在“Document”程序类那里其实是一个链接, 点进去该页面 你便会发现 document 类下面有个叫做 name() 的功能用来返回文档名称,width() 和 height() 则会返回文档尺寸。如果我们想要生成 Krita 已打开文件的信息报表,我们可以编写下面的脚本:

from krita import *

for doc in Krita.instance().documents():
    print(doc.name())
    print(" "+str(doc.width())+"x"+str(doc.height()))

输出结果为

==== Warning: Script not saved! ====
Unnamed
 2480x3508
sketch21
 3508x2480
Blue morning
 1600x900

希望通过上面的介绍,你已经学会了如何检索和使用 Krita API 文档的内容。

Krita 的 API 有许多程序类。你可以在文档页面的左上列表找到它们,也可以点击名称来查看各个功能的 API 文档。 print()dir() 函数可以用来列出 Krita 的全部操作,你只需要把前面例子中的“python_scripter”换成 API 文档中的所需名称即可。

[print([a.objectName(), a.text()]) for a in Krita.instance().actions()]

Python 的 inspect 模块可以用来获得程序类信息。下面的例子展示了如何在控制台里输出一个程序类的信息。

import inspect
def getInfo(target):
    [print(item) for item in inspect.getmembers(target) if not item[0].startswith('_')]

getInfo(Krita.instance())

最后,除了 LibKis 文档之外,你可能还要阅读 Qt 文档,因为 Krita 通过 PyQt 把 Qt API 的绝大多数功能与 Python 进行了对接。这意味着你可以使用 Krita 本身也在使用的 Qt 功能来构建一套带有按钮和输入框的窗口!你可以查阅 Qt 文档PyQt 文档 来学习相关用法,同时别忘了可以参考 Krita 自带的插件的代码设计。

技术细节

在 Windows 环境进行 Python 编程

要在 Windows 7/8/8.1 下面正常运行 Python 环境,请从微软的网站下载并安装 通用 C 运行时 。(Windows 10 已经预装)

Python 2 和 3

Krita 默认为 Python 3 进行编译。

要为 Python 2 进行编译,把下面的参数添加到 Krita 的 cmake 配置:

-DENABLE_PYTHON_2=ON