raster (PIL)

Peter Otten __peter__ at web.de
Thu Jul 23 08:35:37 EDT 2009


superpollo wrote:

> i wrote a program which transforms a string of zeroes ando ones into a
> png file.
> 
> #!/usr/bin/env python
> import Image
> import sys
> bits_in_a_byte = 8
> raster_string = """\
> 00000000000000000000000000000000
> 00100100111100100000100000111100
> 00100100100000100000100000100100
> 00111100111000100000100000100100
> 00100100100000100000100000100100
> 00100100111100111100111100111100
> 00000000000000000000000000000000
> 00000000000000000000000000000000
> 00000000111100100000111100000000
> 00000000100000100000100100000000
> 00000000100000100000111100000000
> 00000000100000100000100000000000
> 00000000111100111100100000000000
> 00000000000000000000000000000000
> """
> raster_lines = raster_string.splitlines()
> high = len(raster_lines)
> wide = len(raster_lines[0])
> bytes_in_a_row = wide/bits_in_a_byte
> bitmap = ""
> for raster_line in raster_lines:
>      for byte_count in range(bytes_in_a_row):
>          first_bit = byte_count*bits_in_a_byte
>          bitmap +=
> chr(int(raster_line[first_bit:first_bit+bits_in_a_byte] , 2))
> im = Image.fromstring("1", (wide , high) , bitmap)
> im.save(sys.stdout , "PNG")
> 
> any suggestions for improvement?

You can simplify the inner loop:

for first_bit in range(0, wide, bits_in_a_byte):
    bitmap += ...

and get rid of a few helper variables.

Here's a different approach:

#!/usr/bin/env python
import Image
import string
import sys

mapping = string.maketrans("01", "\x00\xff")

raster_string = ...

width = raster_string.index("\n")
height = raster_string.count("\n")

raster_string = raster_string.translate(mapping, "\n")

im = Image.fromstring("L", (width, height), raster_string)
im.convert("1").save(sys.stdout, "PNG")

The idea is to move the bit-twiddling from python to code written in C, 
pointless for such a tiny picture but crucial for the performance when you 
want to manipulate larger images.

Peter




More information about the Python-list mailing list