I must preface this, with the fact that I have a working method using bitshift and putpixel, but it is incredibly slow, and I am looking to leverage numpy to speed up the process. I believe I am close, but not quite there. Having timed what I think should work, I'm seeing a 0.3 second improvement in time, hence my motivation.
The current working code:
buff # a binary set of data
im = Image.new("RGBA",(xdim,ydim))
for y in xrange(ydim):
for x in xrange(xdim):
px = buff[x*y]
# the 255 is for the alpha channel which I plan to use later
im.putpixel((x,y),(px&0xF800) >> 8, (px&0x07E0) >> 3, (px&0x001F) <<3, 255))
return im
The code I'm trying to get work looks like this:
im16 = numpy.fromstring(buff,dtype=numpy.uint16) #read data as shorts
im16 = numpy.array(im16,dtype=numpy.uint32) #now that it's in the correct order, convert to 32 bit so there is room to do shifting
r = numpy.right_shift(8, im16.copy() & 0xF800)
g = numpy.right_shift(3, im16.copy() & 0x07E0)
b = numpy.left_shift( 3, im16 & 0x001F)
pA = numpy.append(r,g)
pB = numpy.append(b,numpy.ones((xdim,ydim),dtype=numpy.uint32) * 0xFF) #this is a black alpha channel
img = numpy.left_shift(img,8) #gives me green channel
im24 = Image.fromstring("RGBA",(xdim,ydim),img)
return im24
so the final problem, is that the channels are not combining and I don't believe I should have to do that final bit shift (note that I get the red channel if I don't bit-shift by 8). Assistance on how to combine everything correctly would be much appreciated.
SOLUTION
import numpy as np
arr = np.fromstring(buff,dtype=np.uint16).astype(np.uint32)
arr = 0xFF000000 + ((arr & 0xF800) >> 8) + ((arr & 0x07E0) << 5) + ((arr & 0x001F) << 19)
return Image.frombuffer('RGBA', (xdim,ydim), arr, 'raw', 'RGBA', 0, 1)
the difference is that you need to pack it as MSB(ALPHA,B,G,R)LSB counter intuitive from putpixel, but it works, and works well