Obtaining RGBA pixel values from TImage (or TCanvas)

Hello,

I need to “import” the pixel data from a TCanvas (via TImage) into a Python Image object (PIL). Using TImage::GetArgb() works… but this channel order is not supported by the python image class and so the image colors and text come out horrible. Is there a way to either obtain the array in RGBA order, obtain separate R,G,B data arrays, or internally swizzle the order of the channels (i.e. A->R, R->G, G->B, B->A) so that I can get them in the correct order?

I have tried GetPixels() and GetArray() and they both result in a completely black image (all data returned is 0).

If it was possible to pass a ‘file’ handle directly to TCanvas::Print instead of a text-string, I could get away with writing the TCanvas to a python StrIO object, then reading it from an Image object.

Hi,
1.

IMHO, no need to add this method to TImage.
Loop over array of ARGB values and do:

UChar_t  a = argb >> 24;
UInt_t rgb =  argb & 0x00ffffff;
UInt_y rgba = (rgb <<  8) + a

GetPixels - returns “display specific” array of pixel.
GetArray - returns “vectorized” array of doubles

Please, write this suggestion to another post, because it’s
unrelated to TImage questoin.

I looked at “RGBA format spreading”.
It’s really oftenly used: libjpeg, libpng, and libtiff, imagemagic, OpenGL etc.
Adding TImage::GetRgba method would be usefull.

Thanks for suggestion. Valeriy

Thank you for the reply,

I could do that, but I am using python… on a web-server, and swizling every one of the 60k pixels in each image in python is extremely slow. It would be faster to write them to disk and read them back out. I guess I’ll write some C and interface it with python.

Yes, I was always under the impression that, RGBA is a defacto packing standard

off-topic:

I always thought that python is “extremely fast” interpreter.
Somebody told me that it’s 3 times faster than CINT.
As an author of web-server based on CINT (carrot) I can
recommend to try to switch to carrot from python. It allows to run
compiled CINT scripts which have the same performance as
a normal-optimized compiled C/C++ code. So, convertion speed of ARGB->RGBA
will be the same as for built-in solution.

Hi,
I sent a patch to rootdev with the following log:

Must be in CVS asap. Could you check if it helps?

Thanks. Regards. Valeriy

[quote=“Valeriy Onuchin”]The array must be deleted after usage.
[/quote]
Can you introduce the C++ object instead of the plain array to eliminate the error prone “must be deleted after usage” ? It should be the job of the C++ class dtor rather by the poor user.

When I tried CVS HEAD it produced an image even more incorrect than using GetArgb, I played with the code for an hour or so and finally figured out what was going on. Basically it’s an endianess problem. The array is expected as ABGR. Once I flipped the Blue and Red channels the image colors were fine but it was grainy, I looked at a couple of root-saved images with The GIMP and figured out that TImage returned array had a “weird” alpha channel, setting alpha to 0xFF produced the correct image. The code bellow works, but I am not sure how useful it is:

for (i = 0; i <img>height; i++) { for (j = 0; j <img>width; j++) { idx = y + j; argb = img->alt.argb32[idx]; ret[idx] = (argb & 0xFF00FF00) | (argb & 0x000000FF) <<16>> 16 | 0xFF000000; } y += img->width; }

I am not really sure what I should do now considering this is some weird endieness problem. It wouldn’t be a huge burden to flip two channels, but having to set alpha to 1 makes me a bit uncomfortable. I also tried to find out what ASImage2file does since whatever it does, results in a perfectly correct image; but I couldn’t find the source for it.

[quote]I always thought that python is “extremely fast” interpreter.
Somebody told me that it’s 3 times faster than CINT. [/quote]

That is what I heard as well, python is apparently easier to parse than C++, but I was under the impression that when I am calling a root method from within python I am actually calling into a compiled root library.

Thanks again for the help.

Stou

[quote=“stou”]
I am not really sure what I should do now considering this is some weird endieness problem. It wouldn’t be a huge burden to flip two channels, but having to set alpha to 1 makes me a bit uncomfortable.
Stou[/quote]You can evaluate doc.trolltech.com/3.3/qimage.html
from Qt library which is freely available and can be used from within ROOT application ftp://root.cern.ch/root/doc/chapter27.pdf

At least it does provide the information explicitly via a bunch of the methods like:
doc.trolltech.com/3.3/qimage.html#systemBitOrder
and allows you to control things via
doc.trolltech.com/3.3/qimage.html#swapRGB

Of course, one from for Qt 4.2 doc.trolltech.com/4.2/qimage.html is better. However the Qt 4.x / ROOT integration is not supported officialy yet (due lack of the user’s demand :wink:

Thank you for the links, however I am using Python, not C++.

Then you may be interesting to see
wiki.python.org/moin/PyQt
riverbankcomputing.co.uk/pyqt/
and
“Gui Programming With Python: Using the Qt Toolkit” amazon.com/gp/product/097003 … e&n=283155
google.com/search?hl=en&lr=& … tnG=Search