[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] VideoCapture, PIL, and PyGame



That'll teach me to psuedocode on little sleep.  That should have been:
*dst++ = *src--;

Anyway, in general, it probably isn't worth the effort.  Native
Windows camera support for pygame is coming eventually...

Nirav

On Sun, Jun 14, 2009 at 1:25 AM, Nirav Patel<olpc@xxxxxxxxxxxxxx> wrote:
> I don't know exactly how VideoCapture is implemented, but the camera
> buffer is apparently in BGR color order and the pixels are in reverse
> order.
>
> Thus, you can't use it directly as a Surface.  You could fix the
> upsidedown image by using pygame.image.fromstring() with the last
> argument as True.  It would probably be faster than going through PIL,
> but then once you switch R and B with Numpy, it'll be slower again.
> It would only be worth it if you don't want PIL as a dependancy.
>
> If you want speed, the best way would be to write a C function to
> write to a new Surface, reading from the end of the image to the
> beginning.
>
> A little psuedocode, without all the python API and SDL stuff.
>
> Uint8* src = end_of_camera_buffer;
> Uint8* dst = start_of_pygame_surface;
> for (int i = 0; i < width*height*byte_depth; i++) {
>    *src-- = *dst++;
> }
>
> Nirav
>
> On Sun, Jun 14, 2009 at 12:35 AM, Ian Mallett<geometrian@xxxxxxxxx> wrote:
>> Hi,
>>
>> So, I'm trying to get VideoCapture working with PyGame.  I've modified the
>> standard VideoCapture.py file to make it simpler and easier to read.  I've
>> attached it as well as my program, main.py.
>>
>> VideoCapture.py defines a class Device.  Device has two functions that I'm
>> concerned with: .getBuffer(), which returns (string_data,width,height), and
>> .getImage(), which returns a PIL image made with .getBuffer().
>>
>> I'm trying to get a PyGame surface from all this.  Every code sample I've
>> seen converts the PIL image (returned from .getImage()) back into a string,
>> and then makes a PyGame image with pygame.image.frombuffer(...):
>> im = Camera.getImage()
>> image = pygame.image.frombuffer(im.tostring(), im.size, im.mode)
>>
>> Though this works nicely, it seems terribly inefficient--VideoCapture.py
>> takes the data as a string from .getBuffer(), and makes a PIL image.  The
>> main, main.py, must then change this PIL image back into a string again, and
>> then make a PyGame surface from that.  (Basically:
>> STRING->PIL->STRING->PYGAME).  This setup doesn't fly realtime.  Moreover,
>> it requires an extra dependency, PIL.
>>
>> So, I tried just converting the original string from .getBuffer() directly
>> into a PyGame surface.  (Basically: STRING->PYGAME):
>> data = Camera.getBuffer()
>> image = pygame.image.frombuffer(data[0],(data[1],data[2]),"RGB")
>>
>> But this has problems.  It doesn't crash, but the image is upsidedown and
>> the red and blue color channels appear to be flopped.  I tried fixing it
>> with surfarray, which didn't work.  Then I tried finding what was wrong, and
>> got inconsistent results.
>>
>> How can I get the second method (method 2: STRING->PYGAME) to look like the
>> first method (method 1: STRING->PIL->STRING->PYGAME)?  main.py lets you
>> switch back and forth (press 1 for method 1, 2 for method 2).
>>
>> Ian
>>
>