jhfelectric
jhfelectric

Reputation: 582

How to save pygame Surface as an image to memory (and not to disk)

I am developing a time-critical app on a Raspberry PI, and I need to send an image over the wire. When my image is captured, I am doing like this:

# pygame.camera.Camera captures images as a Surface
pygame.image.save(mySurface,'temp.jpeg')
_img = open('temp.jpeg','rb')
_out = _img.read()
_img.close()
_socket.sendall(_out)

This is not very efficient. I would like to be able to save the surface as an image in memory and send the bytes directly without having to save it first to disk.

Thanks for any advice.

EDIT: The other side of the wire is a .NET app expecting bytes

Upvotes: 8

Views: 17597

Answers (3)

Cees Timmerman
Cees Timmerman

Reputation: 19644

from io import BytesIO
import pygame

name = "temp.jpeg"
surface = pygame.image.load(name)
bf = BytesIO()
pygame.image.save(surface, bf, "png")  # Converts to PNG.
bf.seek(0)
print("First 100 bytes:", bf.read(100))  # Or write to socket.

Upvotes: -1

Chuni
Chuni

Reputation: 9

the fromstring method has been deprecated in PIL and replaced with from bytes

Upvotes: 0

kalhartt
kalhartt

Reputation: 4129

The simple answer is:

surf = pygame.Surface((100,200)) # I'm going to use 100x200 in examples
data = pygame.image.tostring(surf, 'RGBA')

and just send the data. But we want to compress it before we send it. So I tried this

from StringIO import StringIO
data = StringIO()
pygame.image.save(surf, x)
print x.getvalue()

Seems like the data was written, but I have no idea how to tell pygame what format to use when saving to a StringIO. So we use the roundabout way.

from StringIO import StringIO
from PIL import Image
data = pygame.image.tostring(surf, 'RGBA')
img = Image.fromstring('RGBA', (100,200), data)
zdata = StringIO()
img.save(zdata, 'JPEG')
print zdata.getvalue()

Upvotes: 10

Related Questions