raster (PIL)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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