Discussion:
BGRA to RGB/RGBA, fastest way to do so
gm770
2012-09-01 19:52:01 UTC
Permalink
I'm trying to convert a color string buffer, and looking for the fastest way
to do so.
I'm capturing a 2 screen desktop (h=1080, w=3840), but it comes in as BGRA,
and I don't see an obvious way to convert that to RGBA or RGB.

The fastest way I have so far is ~1.78 sec, but I'm sure there must be
something faster.

def toRGBA(BGRA_str):
buf = bytearray(BGRA_str)
for x in xrange(0,len(buf),4):
buf[x], buf[x+2] = buf[x+2], buf[x]
return buf

Slower methods include:
- starting with an empty array, and via loop, appending to create RGB. (~3.8
sec)
- turn the buffer to a list of chars, swap and return the joined results.
(~2.14 sec)



--
View this message in context: http://pygame-users.25799.n6.nabble.com/BGRA-to-RGB-RGBA-fastest-way-to-do-so-tp163.html
Sent from the pygame-users mailing list archive at Nabble.com.
Silver
2012-09-01 20:07:59 UTC
Permalink
Post by gm770
I'm trying to convert a color string buffer, and looking for the fastest way
to do so.
I'm capturing a 2 screen desktop (h=1080, w=3840), but it comes in as BGRA,
and I don't see an obvious way to convert that to RGBA or RGB.
The fastest way I have so far is ~1.78 sec, but I'm sure there must be
something faster.
buf = bytearray(BGRA_str)
buf[x], buf[x+2] = buf[x+2], buf[x]
return buf
- starting with an empty array, and via loop, appending to create RGB. (~3.8
sec)
- turn the buffer to a list of chars, swap and return the joined results.
(~2.14 sec)
--
View this message in context: http://pygame-users.25799.n6.nabble.com/BGRA-to-RGB-RGBA-fastest-way-to-do-so-tp163.html
Sent from the pygame-users mailing list archive at Nabble.com.
From the doc page comments:
As for "BGR" (OpenCV): Just use "RBG" but reverse the string first
and then flip the surface (vertically and horizontally).

I am using this with fromstring:

frame = cvQueryFrame(capture) # get a video frame
using OpenCV
bgr = frame.imageData # this is a string
using BGR
rgb = bgr[::-1] # reverse it to get RGB
im = pygame.image.fromstring(rgb, size, 'RGB') # create pygame surface
im = pygame.transform.flip(im, True, True) # flip it



you could also use map():

x = [buf[x], buf[x+2] for x in xrange(0, len(buf), 4)]## convert to list
format

map(lambda x: [x[2], x[1], x[0], x[3]], bgra) ## returns a list of
four-item lists in RGBA format.


or you could import/export it from pygame:

ARGB = BGRA[::-1]
ARGB_image = pygame.image.fromstring(ARGB, size, "ARGB")
RGBA_str = pygame.image.tostring(ARGB_image, "RGBA")
gm770
2012-09-01 20:52:51 UTC
Permalink
Post by Silver
ARGB = BGRA[::-1]
ARGB_image = pygame.image.fromstring(ARGB, size, "ARGB")
RGBA_str = pygame.image.tostring(ARGB_image, "RGBA")
I saw this trick for BGR, but didn't see how I could get it to work with
BGRA, but here it is. Thanks!
The results are flipped, but that's easy to take care of.
Even with the flip code added in, the speed results are wonderful. ~0.2
sec.

---------------------------------------

def toRGBA(BGRA_str, w, h):
ARGB = BGRA_str[::-1]
size = (w, h)
ARGB_image = pygame.image.fromstring(ARGB, size, "ARGB")
RGBA_str = pygame.image.tostring(ARGB_image, "RGBA")
return RGBA_str

# bmpstr: is the ColorStringBuffer, w,h: is the width and height of the
image in the buffer
bmpstr = toRGBA(bmpstr, w, h)
surface = pygame.image.frombuffer(bmpstr, (w,h), "RGBA")
surface = pygame.transform.flip(surface, True, True)





--
View this message in context: http://pygame-users.25799.n6.nabble.com/BGRA-to-RGB-RGBA-fastest-way-to-do-so-tp163p166.html
Sent from the pygame-users mailing list archive at Nabble.com.

Christoph Gohlke
2012-09-01 20:11:30 UTC
Permalink
Post by gm770
I'm trying to convert a color string buffer, and looking for the fastest way
to do so.
I'm capturing a 2 screen desktop (h=1080, w=3840), but it comes in as BGRA,
and I don't see an obvious way to convert that to RGBA or RGB.
The fastest way I have so far is ~1.78 sec, but I'm sure there must be
something faster.
buf = bytearray(BGRA_str)
buf[x], buf[x+2] = buf[x+2], buf[x]
return buf
- starting with an empty array, and via loop, appending to create RGB. (~3.8
sec)
- turn the buffer to a list of chars, swap and return the joined results.
(~2.14 sec)
Can you use numpy?

RGBA_str = numpy.fromstring(BGRA_str, dtype='uint8').reshape((3840*1080,
4))[:, (2, 1, 0, 3)].tostring()

Christoph
Loading...