[cairo] using ARGB32 surfaces with pygame

Jayesh Salvi jayeshsalvi at gmail.com
Fri Feb 20 23:27:53 PST 2009

Thanks Bill.

So if I get you correctly, what's happening is cairo is creating color 
info in ARGB format. pygame is interpreting it as BGRA, because of the 
byte-order difference. The code I am using is swapping 0th and 2nd 
color, i.e. B and R - thus leading to RGBA. That's the format I am 
feeding to pygame.image.frombuffer.

It sounds like it is inevitable to do this operation when using cairo 
with pygame. I will see how big performance impact it can cause, if at all.

For anyone interested, I at least managed to do the swapping without the 
help of numpy. thanks to: 

    def ARGBtoRGBA(self,str_buf):
        # cairo's ARGB is interpreted by pygame as BGRA due to
        # then endian-format difference this routine swaps B and R
        # (0th and 2nd) byte converting it to RGBA format.
        byte_buf = array.array("B", str_buf)
        num_quads = len(byte_buf)/4
        for i in xrange(num_quads):
            tmp = byte_buf[i*4 + 0]
            byte_buf[i*4 + 0] = byte_buf[i*4 + 2]
            byte_buf[i*4 + 2] = tmp
        return byte_buf.tostring()


Bill Spitzak wrote:
> That message from me is quite out of date.
> Due to Windows using the ARGB32 format, that is what all hardware 
> supports best, and therefore is the correct format for Cairo to use by 
> default.
> Also it appears everybody has agreed that adding "32" to the end of a 
> name means that the name indicates the order of the bytes in a word, 
> an if there is no suffix it indicates the order of the bytes in 
> memory. This new usage seems to be taking over from the previous X 
> mistakes.
> It does sound like your library wants RGBA and (on a little-endian 
> machine) you convert ARGB32 to it by swapping the bytes at 0 and 2.
> Jayesh Salvi wrote:
>> Hi,
>> I am creating FORMAT_ARGB32 surfaces using pycairo and while 
>> rendering them as pygame images, I found them to have different 
>> colors. It looked like there was some incompatibility in RGB order 
>> between pycairo and pygame. After spending some time, I found 
>> following code segment somewhere which fixed the colors.
>>         buf = surface.get_data()
>>         a = numpy.frombuffer(buf,numpy.uint8)
>>         a.shape = (surface.get_width(),
>>                     surface.get_height(),4)
>>         tmp = copy(a[:,:,0])
>>         a[:,:,0] = a[:,:,2]
>>         a[:,:,2] = tmp
>>         return a
>> It looks like two colors are swapped (I suppose R and B, but I am not 
>> sure). But it works.
>> My question is can I avoid doing this? In my app this operation will 
>> occur many times and hence will affect the performance of GUI. Also 
>> it adds a dependency on numpy.
>> I found an old discussion on the mailing list that mentions "ABGR" 
>> color format (which I suppose is what pygame is expecting above)
>> http://lists.cairographics.org/archives/cairo/2005-January/002637.html
>> But at present I didn't find any such format option in pycairo. All 
>> FORMATs that are there today are:
>> ['FORMAT_A1', 'FORMAT_A8', 'FORMAT_ARGB32', 'FORMAT_RGB16_565', 
>> 'FORMAT_RGB24']
>> Can somebody shed some light?
>> Thanks,

code <http://code.google.com/p/altcanvas/> | twit 
<http://www.twitter.com/jyro> | blog <http://jyro.blogspot.com>

More information about the cairo mailing list