#!/usr/bin/env python
#-*- coding:utf-8 -*-
import Image #needs PIL for image handling
import ImageChops
import ImageFont
import ImageDraw
# checks if two images are equal
def equal(im1, im2):
return ImageChops.difference(im1, im2).getbbox() is None
# add a text caption to an image (adds space at the bottom)
def addCaption(im, text, pointSize):
size = im.size
draw = ImageDraw.Draw(im)
textFontLocation = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
topBottomMargin = 5
textFont = ImageFont.truetype(textFontLocation ,pointSize)
textSize = draw.textsize(text, font=textFont) # the size of the text box!
newImage = Image.new(im.mode,\
(im.size[0], im.size[1]+textSize[1]+2*topBottomMargin), "white" )
newImage.paste( im, (0,0) )
draw = ImageDraw.Draw(newImage)
textX = (newImage.size[0] / 2.0) - (textSize[0] / 2.0)
textY = newImage.size[1] - textSize[1] - topBottomMargin
draw.text((textX, textY), text, fill="black", font=textFont)
return newImage
# add a solid border to an image
def addBorder(im, color, thickness):
newImage = Image.new(im.mode,\
(im.size[0]+thickness*2, im.size[1]+thickness*2), color)
newImage.paste( im, (1,1) )
return newImage
# scale an image up or down (doesn't resample, so the pixels are clear)
def scaleImage(im, factor):
newImage = Image.new(im.mode,\
(im.size[0]*factor, im.size[1]*factor), "white" )
newImage.paste( im.transform((im.size[0]*factor, im.size[1]*factor),\
Image.AFFINE,\
(1/float(factor),0,0,0,1/float(factor),0) ),\
(0,0) )
return newImage
def saveImages(im, iteration):
im.save("Catmap%04d.png"%iteration) #save the simple image
#resize image, add border and caption
imageLarge = scaleImage(im, 6)
imageLarge = addBorder(imageLarge, "black", 1)
imageLarge = addCaption(imageLarge, str(iteration), 40)
imageLarge.save("CatmapLargeNumbered%04d.png"%iteration)
# CONTROL STARTS HERE
inFile = "aa-catmap-orig.resized.jpg" #input image
image0 = Image.open(inFile, 'r')
#crop to square if required
if image0.size[0] != image0.size[1]:
n = min(image0.size[0], image0.size[1] )
image0 = image0.crop((0,0,n,n))
else:
n = image0.size[0]
imageOrig = image0.copy() # keep to original image to see when we return to it
image1 = Image.new(image0.mode, (n,n)) # temp image to copy pixels to
pixels1 = image1.load()
# BEGIN THE CAT MAPPING PROCESS
iteration = 0
saveImages(image0, iteration) # save the first image
while True:
pixels0 = image0.load() #reload the iterated image
for x in range(n):# perform the mapping
for y in range(n):
newX = (2*x + y) % n #find new location
newY = (x + y) % n
pixels1[newX, newY] = pixels0[x, y] # copy the pixel over
image0 = image1.copy() #transfer back to image0 for the next iteration
iteration += 1
saveImages(image0, iteration) # save this iteration's image
if equal(image0, imageOrig):
break