Hackpact Day 7: bytes, pixel formats, PIL and to Save
Today I wanted to add the scrolling feature to my canvas, so I can have a canvas larger than the window.
To implement the feature was easy, but then I realized that when I did the “save” function I only made a dump of the screen, not the whole texture, and now the texture was bigger than the screen, so I needed a save method on the RT class.
It wasnt hard to code it, but the problem came when I tryed to save the RGB16F RT, it just didnt work, the pixels in the resulting image looked like it was taking one byte per pixel and channel instead of reading it as a Float, somehow it was obvious, you cant pass an array of bytes to a function and expect it will know how to handle it, but the documentation of PIL (the library used to handle images in python) is crap, they don’t explain well how to specify the pixel format when is 16 or 32 bits and has more than one channel.
I have been searching info all day long and nothing was found, I just end up thinking PIL doesnt support to read images in RGB with channels of more than 8 bits. They say something about a “F” format if you use the fromBuffer function, but the encoder looks like it only allows one channel images. Silly.
Then I had an idea, if I take every pixel and divide it by 256 (when a short is used) I will have a 8 bits precission, indeed I don’t need to save a 16bits image, mainly because not a lot of file formats supports it (and right now Im using JPG).
I tried to do so, to divide every pixel read from the buffer by 256 and store it using 8bits per channel. First, it wasnt easy, because the image is stored using numpy, which I understand, but the documentation of numpy is crap, they don’t tell you some basic things like how to convert from one data type to another, or how to apply a function to every value of the matrix. So finally I discovered how, but it didnt work, it appear like some values where out of bounds.
So after wasting a whole day just to save a image I came up with the simplest idea, to create a temporary RGB image with 8 bits precission and render a quad using the other texture. I’m wasting some memory and performance but it works and it is easy.
No screenshots today or resources today.