Reverse order of bit in repeating seqence of byte string

I

imageguy

I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

blist = list(buffer)
for start in xrange(0,len(blist), 3):
try:
blue = blist[start]
red = blist[start+2]
blist[start] = red
blist[start+2] = blue
except IndexError:
pass

new_buffer = ''.join(blist)

new_buffer is then passed to a wx program to create and image.

Any thoughts comments would be appreciated.

geoff.

PS: I started this post earlier, but I think I hit the send button
too soon. My apologies to the group for sloppy typing.
 
S

Steve Holden

imageguy said:
I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

blist = list(buffer)
for start in xrange(0,len(blist), 3):
try:
blue = blist[start]
red = blist[start+2]
blist[start] = red
blist[start+2] = blue
except IndexError:
pass

new_buffer = ''.join(blist)

new_buffer is then passed to a wx program to create and image.

Any thoughts comments would be appreciated.

geoff.

PS: I started this post earlier, but I think I hit the send button
too soon. My apologies to the group for sloppy typing.
May not be any quicker, but it works:

blues = buffer[0::3]
greens = buffer[1::3]
reds = buffer[2::3]

result = "".join("".join(x) for x in zip(reds, blues, greens))

regards
Steve
 
F

Francesco Bochicchio

imageguy ha scritto:
I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

blist = list(buffer)
for start in xrange(0,len(blist), 3):
try:
blue = blist[start]
red = blist[start+2]
blist[start] = red
blist[start+2] = blue
except IndexError:
pass

new_buffer = ''.join(blist)

new_buffer is then passed to a wx program to create and image.

Any thoughts comments would be appreciated.

geoff.

PS: I started this post earlier, but I think I hit the send button
too soon. My apologies to the group for sloppy typing.
You could try the same algorithm on an array.array object : it might be
faster.

Ciao
 
T

Terry Reedy

imageguy said:
I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'

For speed, I would look at PIL or pygame for existing function, or use
numpy -- read into 2-d array, swap first and third members, flatten.
 
M

MRAB

Francesco said:
imageguy ha scritto:
I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

blist = list(buffer)
for start in xrange(0,len(blist), 3):
try:
blue = blist[start]
red = blist[start+2]
blist[start] = red
blist[start+2] = blue
except IndexError:
pass

new_buffer = ''.join(blist)

new_buffer is then passed to a wx program to create and image.

Any thoughts comments would be appreciated.

geoff.

PS: I started this post earlier, but I think I hit the send button
too soon. My apologies to the group for sloppy typing.
You could try the same algorithm on an array.array object : it might be
faster.
>>> s = "012345678"
>>> from array import array
>>> a = array("b", s)
>>> a array('b', [48, 49, 50, 51, 52, 53, 54, 55, 56])
>>> a[0::3], a[2::3] = a[2::3], a[0::3]
>>> a array('b', [50, 49, 48, 53, 52, 51, 56, 55, 54])
>>> a.tostring()
'210543876'
 
B

bearophileHUGS

imageguy:
I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function
MRAB:
 >>> a.tostring()
'210543876'

That's not the required 'rbgrbgrbgrbg', but you are close to a correct
solution:
from array import array
s = 'bgrbgrbgrbgr'
a = array("B", s) # uppercase B
a[0::3], a[1::3], a[2::3] = a[2::3], a[0::3], a[1::3]
a.tostring()
'rbgrbgrbgrbg'

Bye,
bearophile
 
J

John Machin

I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

For some very strange definition of "works". You say you have 'bgr'
and want to convert it to 'rbg'. The following code converts 'bgr' to
'rgb', which is somewhat more plausible, but not what you said you
wanted.
blist = list(buffer)
for start in xrange(0,len(blist), 3):
   try:
        blue = blist[start]
        red = blist[start+2]
        blist[start] = red
        blist[start+2] = blue
   except IndexError:
       pass

new_buffer = ''.join(blist)
 
G

Gary Herron

imageguy said:
I am looking for the most efficient method of replacing a repeating
sequence in a byte string returned from a imaging .dll, connected via

I receive the byte string with the following sequence 'bgrbgrbgrbgr'
and I would like to convert this to 'rbgrbgrbgrbg'
FWIW, the string is created using ctypes.create_string_buffer function

The following code works but feels a bit clunk and is rather slow too.

blist = list(buffer)
for start in xrange(0,len(blist), 3):
try:
blue = blist[start]
red = blist[start+2]
blist[start] = red
blist[start+2] = blue
except IndexError:
pass

new_buffer = ''.join(blist)

new_buffer is then passed to a wx program to create and image.

Any thoughts comments would be appreciated.

geoff.

PS: I started this post earlier, but I think I hit the send button
too soon. My apologies to the group for sloppy typing.
I've not seen anyone mention numpy yet, but
numpy has a nice (efficient) way to do this:
import numpy
s = 'bgrBGRcbaCBA'
a=numpy.array(s, 'c') # Initialize an array
a.shape = (4,3) # Reinterpret as a ?? by 3 array
b=a[...,::-1] # reverse the second dimension
print b.tostring() # Convert back to a string.
rgbRGBabcABC


Gary Herron
 
I

imageguy

For some very strange definition of "works". You say you have 'bgr'
and want to convert it to 'rbg'. The following code converts 'bgr' to
'rgb', which is somewhat more plausible, but not what you said you
wanted.

Well that's embarrassing ... you are correct. I need to convert from
'bgr' to 'rgb'

Thanks to all others for suggestions

FWIW, I realized the the C.types string buffer is/was mutable so
settled on this;

for start in xrange(0, ctypes.sizeof(buffer), 3):
if buffer[start] != buffer[start+2]:
#only need to swap the bits if they are different. ie if
both are white or black, no change is required.
blue, red = buffer[start], buffer[start+2]
buffer[start], buffer[start+2] = red, blue

This was about 30-40% faster that converting to list, processing and
then converting back again.

Will try the array module too
.... but I think I need to find a new graphic package rather that makes
working with the bits easier.

g.
 
J

John Machin

For some very strange definition of "works". You say you have 'bgr'
and want to convert it to 'rbg'. The following code converts 'bgr' to
'rgb', which is somewhat more plausible, but not what you said you
wanted.

Well that's embarrassing ... you are correct.  I need to convert from
'bgr' to 'rgb'

Thanks to all others for suggestions

FWIW, I realized the the C.types string buffer is/was mutable so
settled on this;

for start in xrange(0, ctypes.sizeof(buffer), 3):
    if buffer[start] != buffer[start+2]:
         #only need to swap the bits if they are different.  ie if
both are white or black, no change is required.
         blue, red = buffer[start], buffer[start+2]
         buffer[start], buffer[start+2] = red, blue

You are likely find that using
buffer[start], buffer[start+2] = buffer[start+2], buffer[start]
is faster.

Cheers,
John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top