Anonymous avatar Anonymous committed feb6f7d

pygame.image tostring and fromstring

Comments (0)

Files changed (4)

     w = surf.w
 
     if flipped:
-        h_range = range(surf.h - 1, 0, -1)
+        h_range = range(surf.h - 1, -1, -1)
     else:
         h_range = range(surf.h)
 
         pixels = surf.pixels.to_string()
         surface.unlock()
 
-        if pitch == w:
+        if pitch == w and not flipped:
             rows = [pixels] # easy exit
         else:
             for y in h_range:
                             ((c & Amask) >> Ashift) << Aloss ) \
                           for c in surf.pixels]
         surface.unlock()
+        pitch /= surf.format.BytesPerPixel
         if format == 'RGB':
             for y in h_range:
                 rows.append(''.join([ chr(c[0]) + chr(c[1]) + chr(c[2]) \
         `size` : (int, int)
             Width, height of the image.
         `format` : str
-            One of 'P', 'RGB', 'RGBX', 'RGBA' or 'ARGBA'
+            One of 'P', 'RGB', 'RGBA' or 'ARGB'
         `flipped` : bool
             If True, data is ordered from bottom row to top.
 
     :rtype: `Surface`
     '''
+    width, height = size
+    if format == 'P':
+        Rmask = 0
+        Gmask = 0
+        Bmask = 0
+        Amask = 0
+        depth = 8
+        pitch = width
+    elif format == 'RGB':
+        Rmask = 0x000000ff
+        Gmask = 0x0000ff00
+        Bmask = 0x00ff0000
+        Amask = 0x00000000
+        depth = 24
+        pitch = width * 3
+    elif format in ('RGBA', 'RGBX'):
+        Rmask = 0x000000ff
+        Gmask = 0x0000ff00
+        Bmask = 0x00ff0000
+        if format == 'RGBA':
+            Amask = 0xff000000
+        else:
+            Amask = 0x00000000
+        depth = 32
+        pitch = width * 4
+    elif format == 'ARGB':
+        Rmask = 0x0000ff00
+        Gmask = 0x00ff0000
+        Bmask = 0xff000000
+        Amask = 0x000000ff
+        depth = 32
+        pitch = width * 4
+    if len(string) != pitch * height:
+        raise ValueError, \
+              'String length does not equal format and resolution size'
+    if flipped:
+        string = ''.join([string[y*pitch:y*pitch+pitch] \
+                          for y in range(height - 1, -1, -1)])
+    surf = SDL_CreateRGBSurfaceFrom(string, width, height, depth, pitch,
+                                    Rmask, Gmask, Bmask, Amask)
+
+    return pygame.surface.Surface(surf=surf)
+
 def frombuffer(string, size, format):
     '''Create a new Surface that shares data inside a string buffer.
 
         `size` : (int, int)
             Width, height of the image.
         `format` : str
-            One of 'P', 'RGB', 'RGBX', 'RGBA' or 'ARGBA'
+            One of 'P', 'RGB', 'RGBA', 'RGBX' or 'ARGB'
     
     :rtype: `Surface`
     '''
-
-
-try:
-    import pygame.imageext
-    _is_extended = True
-except ImportError:
-    _is_extended = False
+    return fromstring(string, size, format)
             if isinstance(arg, Rect):
                 object.__setattr__(self, '_r', copy.copy(arg._r))
                 return
+            elif isinstance(arg, SDL.SDL_Rect):
+                object.__setattr__(self, '_r', copy.copy(arg))
+                return
             elif hasattr(arg, 'rect'):
                 arg = arg.rect
                 if callable(arg):

pygame/surface.py

         return format.Rloss, format.Gloss, format.Bloss, format.Aloss
 
 
-def _surface_blit(destobj, srcobj, destrect, srcrect, special_flags):
+def _surface_blit(destobj, srcobj, dstrect, srcrect, special_flags):
     dst = destobj._surf
     src = srcobj._surf
     subsurface = None

test_pygame/image_string.py

+#!/usr/bin/env python
+
+'''Check that pygame.image tostring and fromstring functions work correctly
+with PIL's fromstring and tostring methods.  Press a key to advance each
+test.
+'''
+
+__docformat__ = 'restructuredtext'
+__version__ = '$Id$'
+
+import os
+import sys
+
+import pygame
+from pygame.locals import *
+import Image
+
+def show_image(surf, message):
+    screen = pygame.display.set_mode(surf.get_size())
+    pygame.display.set_caption(message)
+
+    screen.blit(surf, (0, 0))
+    pygame.display.flip()
+
+    while True:
+        event = pygame.event.wait()
+        if event.type == KEYDOWN:
+            break
+        elif event.type == QUIT:
+            sys.exit(0)
+
+if __name__ == '__main__':
+    pygame.init()
+    pygame.display.init()
+
+    if len(sys.argv) > 1:
+        image_file = sys.argv[1]
+    else:
+        image_file = os.path.join(os.path.dirname(sys.argv[0]), 
+                                  '../test/sample.bmp')
+
+    flip_str = ''
+    for flipped in (False, True):
+        if flipped:
+            flip_str = ' flipped'
+        else:
+            flip_str = ''
+        # Load image with PIL, use pygame.image.fromstring with various formats
+        pil_image = Image.open(image_file)
+        for format in ('P', 'RGB', 'RGBA'):
+            pil_converted = pil_image.convert(format)
+            pil_string = pil_converted.tostring()
+            pygame_image = pygame.image.fromstring(pil_string, 
+                                                   pil_converted.size, 
+                                                   format, flipped)
+            if pil_converted.mode == 'P':
+                # Gaa, no way to retrieve palette directly
+                pal_image = pil_converted.resize((256, 1))
+                pal_image.putdata(range(256))
+                palette = list(pal_image.convert('RGB').getdata())
+                pygame_image.set_palette(palette)
+            show_image(pygame_image, 'frombuffer %s %s' % (format, flip_str))
+
+        # Load image with pygame, use pygame.image.tostring with various formats,
+        # save image with PIL and then check result
+        pygame_image = pygame.image.load(image_file)
+        for format in ('P', 'RGB', 'RGBA'):
+            if format == 'P' and pygame_image.get_bitsize() != 8:
+                continue
+            pygame_string = pygame.image.tostring(pygame_image, format, flipped)
+            pil_image = Image.fromstring(format, 
+                                         pygame_image.get_size(), 
+                                         pygame_string)
+            if format == 'P':
+                palette = pygame_image.get_palette()
+                palette = reduce(lambda a,b: a + list(b), palette, [])
+                pil_image.putpalette(palette)
+            temp_file = os.tmpfile()
+            pil_image.save(temp_file, 'png')
+            temp_file.seek(0)
+            displayed_image = pygame.image.load(temp_file, 'temp.png')
+            show_image(displayed_image, 'tostring %s %s' % (format, flip_str))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.