Can only read and write to Blue channel from Node::channels() list, no matter which channel is accessed (Channel::name() works correctly however). STEPS TO REPRODUCE 1. Create new document (something small, say 2x2 pixels) 2. Fill with yellow (255, 255, 0) 3. Run the following script: from krita import * from PyQt5.QtCore import QByteArray, QRect doc = Krita.instance().activeDocument() layers = doc.rootNode().childNodes() channels = layers[0].channels() greenChan = channels[1] print(greenChan.name()) # Prints 'Green' rect = greenChan.bounds() # Print out 1 for chan in channels: print("Channel: " + chan.name()) px = chan.pixelData(rect) print(px) val = int(128) pxData = greenChan.pixelData(rect) pxData.fill(val.to_bytes(1, byteorder='little')) greenChan.setPixelData(pxData, rect) # Print out 2 for chan in channels: print("Channel: " + chan.name()) px = chan.pixelData(rect) print(px) doc.refreshProjection() OBSERVED RESULT Print out 1 in above script prints all \x00s for all channels Print out 2 in above script prints all \x80s for all channels Image is pale yellow (255, 255, 128) EXPECTED RESULT Print out 1 should print \x00 for Blue channel and \xFF for other channels Print out 2 should print \x00 for Blue, \x80 for Green and \xFF for Red/Alpha Image should be orange (255, 128, 0) SOFTWARE VERSIONS (available in About System) Krita Version: 4.1.5 Qt Version (compiled): 5.9.3 Version (loaded): 5.9.3 OS Information Build ABI: x86_64-little_endian-llp64 Build CPU: x86_64 CPU: x86_64 Kernel Type: winnt Kernel Version: 6.1.7601 Pretty Productname: Windows 7 SP 1 (6.1) Product Type: windows Product Version: 7sp1 OpenGL Info **OpenGL not initialized** ADDITIONAL INFORMATION Same behaviour occurs in Krita 4.1.3. Same behaviour occurs no matter which channel is accessed
Yes, this is caused by the following code in Channel.cpp ln 163: stream << (quint8) *srcIt.rawDataConst(); Basically it is taking the pixel data, which is a list of quint 8 and only returning the first channel. So for 8 and 16 int that is the blue channel, and for 16 and 32 float that is the red channel. Similarly, setPixelData needs to be looked at as well, as it sets the whole pixel to the pixeldata value. boud, I am assigning this to you because I am still kinda bad with bytearrays :D
Git commit e039f03926694fbca5efd75b76c71af5dfaefadf by Boudewijn Rempt. Committed on 30/10/2018 at 13:39. Pushed by rempt into branch 'master'. Fix reading and writing Channels from Python M +8 -8 libs/libkis/Channel.cpp https://commits.kde.org/krita/e039f03926694fbca5efd75b76c71af5dfaefadf
Git commit 96977605adddf0e7a91a07a0d0dfc0c0224d857e by Boudewijn Rempt. Committed on 30/10/2018 at 13:52. Pushed by rempt into branch 'master'. Add a unittest for the channel conversion M +24 -1 libs/libkis/tests/TestChannel.cpp M +1 -0 libs/libkis/tests/TestChannel.h https://commits.kde.org/krita/96977605adddf0e7a91a07a0d0dfc0c0224d857e
I've downloaded the nightly build that contains the above commits, and while it works for the provided example, it fails on others, especially on straight copying one channel to another. Channel pixelData now appears to be four times longer than needed (A 2x2 image will now return a QByteArray with 16 bytes rather than 4). Channel data for non-blue channels seems to be offsets of blue channel as well: A 2x2 image will print out (for each channel) Blue: b'\x00\x00\x00\xYY\x00\x00\x00\xYY\x00\x00\x00\xYY\x00\x00\x00\xYY' Green: b'\x00\x00\x00\xYY+1\x00\x00\x00\xYY+1\x00\x00\x00\xYY+1\x00\x00\x00\xYY+1' Red: b'\x00\x00\x00\xYY+2\x00\x00\x00\xYY+2\x00\x00\x00\xYY+2\x00\x00\x00\xYY+2' Alpha: b'\x00\x00\x00\xYY+3\x00\x00\x00\xYY+3\x00\x00\x00\xYY+3\x00\x00\x00\xYY+3' where YY+Z can overflow into the byte before it. e.g., If the image has xFF blue, the alpha channel will be four copies of \x00\x00\x01\x02 This overflowing also affects the filling. If we have a white 2x2 image, and just simply copy the blue channel to the red with rect = QRect(0,0,doc.width(),doc.height()) channels[2].setPixelData(channels[0].pixelData(rect), rect) the image should stay white but becomes three teal pixels and a white pixel. It also appears can't retrieve channel data for any channel but blue. Also, while I believe it's just a manifestation of the above overflowing, copying the blue channel into another channel on a larger image causes an odd stretching and wrapping effect (see attachments)
Created attachment 116176 [details] Copying blue channel from this image
I don't seem to be able to upload a picture (Keeping getting a server error), so here is an imgur link https://i.imgur.com/Q5a5mg7.png
Git commit f8d86fc35bdf94ed7a78b023125e9f1e13f1b990 by Boudewijn Rempt. Committed on 20/11/2018 at 08:25. Pushed by rempt into branch 'krita/4.1'. Fix reading and writing Channels from Python M +8 -8 libs/libkis/Channel.cpp https://commits.kde.org/krita/f8d86fc35bdf94ed7a78b023125e9f1e13f1b990