This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Transformation mask (move) layer in python

Tags: None
(comma "," separated)
gobber
Registered Member
Posts
8
Karma
0
Hi everyone,
I'm trying to implement a chromatic aberration filter in Krita. So far I have not found a plugin / extension for such an effect anywhere, so I decided to try it myself, and learn some Krita scripting in the process.

To start, I mocked up the following layer setup by hand in Krita:
- "Chromatic aberration" Group
--- "Red channel" Clone Layer (from Source Image) [Addition]
------ Transform Mask
------ Filter Mask (Color adjustment)
--- "Green channel" Clone Layer (from Source Image) [Addition]
------ Transform Mask
------ Filter Mask (Color adjustment)
--- "Blue channel" Clone Layer (from Source Image) [Normal]
------ Transform Mask
------ Filter Mask (Color adjustment)
- Source Image

So the general idea is that I have 3 clone layers of the source image, and each clone layer has a filter mask applied (which squishes everything but the desired color channel to zero) and a transform mask. The Red channel is shifted X pixels left, the Green X pixels down, and the Blue X pixels right.
The three resulting shifted color channels are then added together, to give the final filtered image. (with X == 0, we should just get the original image back)

What I'd like to do is to construct this behemoth from a python script. Creating clone layers and Filter masks are easy enough, but so far I have not found any documentation or functions with which I could add Transform Masks.

The best I could get are actions, such as "movetool-move-down", but I've tried applying this action in a short script, and it doesn't seem to have any effect.

Any help you could give me would be greatly appreciated!


To illustrate what I'm doing, this is the layer setup in Krita 4.4.2 on Mac
Image
This is an example original image
Image
This is the example image with the filter applied
Image

Thanks,
Chris
User avatar
tymond
KDE Developer
Posts
240
Karma
5
> The best I could get are actions, such as "movetool-move-down", but I've tried applying this action in a short script, and it doesn't seem to have any effect.

You need to use doc.waitForDone() after actions to see the effect.

In general it's better to ask about such things on krita-artists.org since there are quite a few users making Python plugins.
gobber
Registered Member
Posts
8
Karma
0
Thank you very much! I'll check out the krita-artists.org site, thank you for the heads-up!
User avatar
Animtim
Registered Member
Posts
259
Karma
0
OS
Hi,

Interesting project :)
For information, you can do exactly the same in Krita more easily without using filters or addition mode...
Just make 2 clones of the image (to have 3 layers of the image), and in the properties of each of these, disable all the channels (including alpha) except one of the color channels for each, so you'll have one layer for R, one for G and one for B. Of course you also need an opaque layer below...
Then move the layers and done.

Image
gobber
Registered Member
Posts
8
Karma
0
Thanks @Animtim, that's a much cleaner take than the one I had. I like that disabling channels in a Krita layer essentially makes those channels see-through, so the addition Just Works.

So I still need to add the transform mask to each layer - and I am not sure if I can move each layer by a specific number of pixels directly from code, or whether I have to use the "movetool-move-*" actions to do this... is there some other way to directly move a Node?
User avatar
tymond
KDE Developer
Posts
240
Karma
5
You can use a method from Node class: move(x, y).

And then after that, you need to use either doc.waitForDone() or doc.refreshProjection() or both, although I think just waitForDone() should be enough.

In general I find it easy to look around the c++ code: https://invent.kde.org/graphics/krita/- ... ibs/libkis (check out the .h files). And only if I can't find something, then I look through actions: https://scripting.krita.org/action-dictionary
gobber
Registered Member
Posts
8
Karma
0
I tinkered a bit further, and found the following in the Scripter:

Code: Select all
from krita import *
activeView = Krita.instance().activeWindow().activeView()
activeDocument = activeView.document()
activeNode = newDocument.activeNode()
activeNode.move(10, 10)

This ^ has no effect when run.
However, after I run it, and then manually add a Transform Mask (right click layer -> Add -> Transform Mask), the layer magically jumps to (10,10).

Also, if there was already a Transform Mask present, running the script has no effect.
It has to be done in the sequence:
a) make sure the selected layer has no transform mask
b) run the script
c) instantiate a Transform Mask on the layer
then the layer moves to (10,10).

So my question is now, can I instantiate a Transform Mask from python in Krita?
gobber
Registered Member
Posts
8
Karma
0
tymond wrote:You can use a method from Node class: move(x, y).

And then after that, you need to use either doc.waitForDone() or doc.refreshProjection() or both, although I think just waitForDone() should be enough.

In general I find it easy to look around the c++ code: https://invent.kde.org/graphics/krita/- ... ibs/libkis (check out the .h files). And only if I can't find something, then I look through actions: https://scripting.krita.org/action-dictionary


Great, the combination of
Code: Select all
doc.waitForDone()
doc.refreshProjection()

works perfectly for me now!
Previously I only had one of them, and that didn't seem to work for me, which is why I gave up on it.

Thanks!
User avatar
tymond
KDE Developer
Posts
240
Karma
5
When you finish the plugin, make sure to publish it on krita-artists.org, then I will add it to the Resources page in Krita Manual too :) (here: https://docs.krita.org/en/resources_pag ... on-plugins). Looks nicely useful!


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Sogou [Bot], Yahoo [Bot]