raster (PIL)

2009-07-23 Thread superpollo

hi.

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 = \

0010010000101000
00100100101010100100
00001110001010100100
00100100101010100100
0010010000000000


0010
10101001
1010
10101000
00001000


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?

bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread Diez B. Roggisch
superpollo wrote:

 hi.
 
 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 = \
 
 0010010000101000
 00100100101010100100
 00001110001010100100
 00100100101010100100
 0010010000000000
 
 
 0010
 10101001
 1010
 10101000
 00001000
 
 
 raster_lines = raster_string.splitlines()
 high = len(raster_lines)
 wide = len(raster_lines[0])
 bytes_in_a_row = wide/bits_in_a_byte

This will give you the wrong result if not divideable by 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?

Instead of 

res = 
for ...:
res += ...

use 

res = []
for ...:
res.append(...)

.join(res)

There are some optimizations for the +=-op on strings, but I'm not sure how
far they go, and the other form is safer.

Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread Peter Otten
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 = \
 
 0010010000101000
 00100100101010100100
 00001110001010100100
 00100100101010100100
 0010010000000000
 
 
 0010
 10101001
 1010
 10101000
 00001000
 
 
 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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread superpollo

Diez B. Roggisch wrote:

superpollo wrote:

...

high = len(raster_lines)
wide = len(raster_lines[0])
bytes_in_a_row = wide/bits_in_a_byte



This will give you the wrong result if not divideable by bits_in_a_byte. 



then maybe:

#!/usr/bin/env python
import Image
import sys
bits_in_a_byte = 8
raster_string = \
00
0010010000101000
00100100101010100100
00001110001010100100
00100100101010100100
0010010000000000


0010
10101001
1010
10101000
00001000


raster_lines = raster_string.splitlines()
high = len(raster_lines)
wide = len(raster_lines[0])
bytes_in_a_row = wide/bits_in_a_byte
wide_for_real = bytes_in_a_row*bits_in_a_byte
if wide_for_real:
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_for_real , high) , bitmap)
im.save(sys.stdout , PNG)

bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread superpollo

Peter Otten wrote:

superpollo wrote:



i wrote a program which transforms a string of zeroes ando ones into a
png file.

...

any suggestions for improvement?

...

Here's a different approach:

...
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.


very very interesting... you know i come from a lower level language 
approach (C/Pascal) so i find it difficult (but full of fascination) to 
adapt to such a different and much simpler way of thinking.


anyways, thanks a lot.

bye

--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread superpollo

Peter Otten wrote:
...

Here's a different approach:

...

raster_string = ...

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


your approach has a funny side-effect: try to remove just one zero from 
the first line of the raster ;-)


bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread superpollo

Peter Otten wrote:
...

im.convert(1).save(sys.stdout, PNG)

...

a q about pil:

im.convert(1)

is different from:

im2 = im.convert(1)

right?

in the former im is changed (the method applies to im) but in the latter 
im is unchanged (first im is copied unto im2 and then the method is 
applied to im2)... am i right?


bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread Diez B. Roggisch
superpollo wrote:

 Diez B. Roggisch wrote:
 superpollo wrote:
 ...
high = len(raster_lines)
wide = len(raster_lines[0])
bytes_in_a_row = wide/bits_in_a_byte
 
 
 This will give you the wrong result if not divideable by bits_in_a_byte.
 
 
 then maybe:
 
 #!/usr/bin/env python
 import Image
 import sys
 bits_in_a_byte = 8
 raster_string = \
 00
 0010010000101000
 00100100101010100100
 00001110001010100100
 00100100101010100100
 0010010000000000
 
 
 0010
 10101001
 1010
 10101000
 00001000
 
 
 raster_lines = raster_string.splitlines()
 high = len(raster_lines)
 wide = len(raster_lines[0])
 bytes_in_a_row = wide/bits_in_a_byte
 wide_for_real = bytes_in_a_row*bits_in_a_byte

No. Because that would skip up to 7 bits.

Instead, do

bytes_in_a_row = wide/bits_in_a_byte
if wide % bits_in_a_byte:
   bytes_in_a_row += 1

Diez
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread Peter Otten
superpollo wrote:

 Peter Otten wrote:
 ...
 im.convert(1).save(sys.stdout, PNG)
 ...
 
 a q about pil:
 
 im.convert(1)
 
 is different from:
 
 im2 = im.convert(1)
 
 right?
 
 in the former im is changed (the method applies to im) but in the latter
 im is unchanged (first im is copied unto im2 and then the method is
 applied to im2)... am i right?

No. A method has no clue whether its result is used or discarded. Therefore

im.convert(1)

creates a new image in the specified mode, too, which is discarded 
immediately. If you don't need the result you probably shouldn't call the 
method at all.

Peter


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread superpollo

Peter Otten wrote:

superpollo wrote:



Peter Otten wrote:
...


im.convert(1).save(sys.stdout, PNG)


...

a q about pil:

im.convert(1)

is different from:

im2 = im.convert(1)

right?

in the former im is changed (the method applies to im) but in the latter
im is unchanged (first im is copied unto im2 and then the method is
applied to im2)... am i right?



No. A method has no clue whether its result is used or discarded. Therefore

im.convert(1)

creates a new image in the specified mode, too, which is discarded 
immediately.


but in:

im.convert(1).save(sys.stdout, PNG)

the new (anonymous) image created by .convert is not discarded 
*immediately*, i mean *before* the .save method is called on it, right?


bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: raster (PIL)

2009-07-23 Thread Peter Otten
superpollo wrote:

 Peter Otten wrote:
 superpollo wrote:
 
 
Peter Otten wrote:
...

im.convert(1).save(sys.stdout, PNG)

...

a q about pil:

im.convert(1)

is different from:

im2 = im.convert(1)

right?

in the former im is changed (the method applies to im) but in the latter
im is unchanged (first im is copied unto im2 and then the method is
applied to im2)... am i right?
 
 
 No. A method has no clue whether its result is used or discarded.
 Therefore
 
 im.convert(1)
 
 creates a new image in the specified mode, too, which is discarded
 immediately.
 
 but in:
 
 im.convert(1).save(sys.stdout, PNG)
 
 the new (anonymous) image created by .convert is not discarded
 *immediately*, i mean *before* the .save method is called on it, right?

Of course. Think of it as a shortcut for

tmp = im.convert(...)
tmp.save(...)
del tmp

Peter


-- 
http://mail.python.org/mailman/listinfo/python-list