Data access in scripting
boud at valdyas.org
Thu Nov 17 20:44:42 CET 2005
On Thu, 17 Nov 2005, Cyrille Berger wrote:
> I have allready started to speak about it on irc. So the question is how do we
> give access to value of a pixel in the scripts ?
> So what do we want :
> - easy to use
> - ensure that scripts are as much as possible colorspace independant
> I see two possible solutions to achieve that :
> - a Pixel class with two functions : get(channelnb) set(channelnb)
> - a Pixel class with functions with the name of the channel (problem, if I
> write a script for rgb, it won't work in cmyk, except if we use an equivalent
> of QColor)
> Well we can also have the two ways of data access in one single class.
> But in both case, we have the problem of colorspace independance to solve
> (there was a suggestion of using XYZ or LAB sometimes ago, but it was
> Maybe someone as something else in mind ?
> Btw, I would like some potential users to answer, if there are some on the
> mailing list, please tell your opinion.
A few constraints and requirements:
* Scripts don't have the same stringent performance requirements our filters, tools,
colorspaces and other plugins have, so we don't need to force script writers to
work with the raw byte pointers -- not that that would work, either.
* I'm opposed to trying to hide Qt from the scripting api, if only because, with
Krita being GPL, that would be futile. Giving script writers access to the image data
in QByteArrays would be possible. Indeed, that's what I intend for the dcop bindings.
Those will be close wrappers of the interfaces and objects Krita exposes to plugins,
with QByteArrays around all pointers. Writers of dcop scripts would then pass the
QByteArray to colorspace functions to get results.
* We still need a way to alert the user about filters, tools and scripts that only work
with a subset of colorspaces, such as 8-bit rgb. There is enough support in Krita's api
for 8-bit rgb scripts: not just the to and from QColor, but also the QImage conversion
functions would work out there -- a script could simply call convertToQImage and
convertFromQImage and the script language wrappers around QImage and QColor to do its thing.
* Limiting the scripting interface to 8 bit rgb would be a mistake.
* If we add a type describer to the channel descriptor, then it would be easier to get
the correct datatype for a particular channel, and if we can somehow make a difference
between a painterly colorspace, a colorspace like rgb and a colorspace like hsv (Casper
knows the right terms, I'm sure), it may be possible, with a lot of effort, to write a
script that can handle stuff the right way.
* But it may be easier to have the script get the bytes in the rect, convert it to the
representation it can handle (preferably a 16-bit representation), do its thing, and
then convert it back. The snag here is loss of precision, which seemed severe when going
to 16 bit XYZ and back; I'm not sure that that's not surmountable. We ought to ask on
the lcms mailing list, I guess. Maybe not even use lcms here, but a plain, profile-less
conversion function, i.e, add toLAB16 and fromLAB16 to the colorspaces. Then scripts
can know what they've got.
Now, how I would like to write a script would be something like:
cs = device.colorSpace();
for pixel in device.getPixels(10,10,100,200):
# invert the pixel first, just for fun
# now, if the colorspace is wet, make it wetter
if cs.name == "WET":
# Increase luminance for that wet look
labPixel = pixel.toLab()
labPixel.l - labPixel.l * 0.2
Or something like that.
Be creative, don't limit scripts to 8 bit rgb -- once wet layers are working people
will want to mess with that from scripts -- but it's okay to have scripts limit themselves
to one colorspace type (still need the hooks to enable, disable scripts and plugins
based on active colorspace) and don't hide the colorspace interface from the scripts.
More information about the kimageshop