JPEG to Text and Blocks

Converting a .jpg image to a text file containing data useable with ipythonblocks.

In [1]:
from PIL import Image

Open up an image of Starry Night by Vincent van Gogh that I pulled from the MOMA website.

In [2]:
im = Image.open('starry_night.jpg')
In [3]:
im.size
Out[3]:
(500, 398)

The image is a bit bigger than I want for use with ipythonblocks. Tables on the order of 100x100 seem to be big enough without slowing down the browser too much. Cutting each dimension in half to 125x100 should do the trick. Always use antialiasing when decreasing the size of an image.

In [4]:
im = im.resize((125, 100), Image.ANTIALIAS)

The getdata() method gives me an iterable sequence of RGB tuples starting with the top left image pixel and going down the image row by row.

In [5]:
imdata = im.getdata()
In [6]:
imdata[0]
Out[6]:
(121, 109, 84)
In [7]:
len(imdata)
Out[7]:
12500

I want to write out a file with the following format:

# width height
125 100
# block size
4
# initial color
0 0 0
# row column red green blue
0 0 121 109 84
...
In [8]:
import os
import itertools
In [9]:
with open('starry_night.txt', 'w') as f:
    s = ['# width height', '{0} {1}'.format(im.size[0], im.size[1]),
         '# block size', '4',
         '# initial color', '0 0 0',
         '# row column red green blue']
    f.write(os.linesep.join(s) + os.linesep)
    
    for ((row, col), colors) in itertools.izip(itertools.product(xrange(im.size[1]), xrange(im.size[0])), imdata):
        things = [str(x) for x in (row, col) + colors]
        f.write(' '.join(things + ['\n']))

Make sure it worked...

In [10]:
!head starry_night.txt
# width height
125 100
# block size
4
# initial color
0 0 0
# row column red green blue
0 0 121 109 84 
0 1 122 115 99 
0 2 117 110 96 

And, for kicks, display imdata with ipythonblocks.

In [11]:
from ipythonblocks import BlockGrid
In [12]:
grid = BlockGrid(125, 100, block_size=4, lines_on=False)
In [13]:
for block, colors in itertools.izip(grid, imdata):
    block.rgb = colors
In [14]:
grid
Out[14]: