# Playing with measuring color distances # Cleaned-up transcript from an ipython session, mostly experimental. # The actual compression algorithm probably won't use this. from dither import * def distance(x, y): return 2.5*((x[0]-y[0])/255)**2 + 4*((x[1]-y[1])/255)**2 + 2.5*((x[2]-y[2])/255)**2 distances = {(i,j): distance(PICO_RGB[i],PICO_RGB[j]) for i in range(len(PICO_RGB)) for j in range(len(PICO_RGB))} def rect_distance_sum(img1, img2, xy1, xy2): """Returns summed color distance of two images, using a rectangular mask""" result = 0.0 x1, y1 = xy1 x2, y2 = xy2 for y in range(y1, y2): for x in range(x1, x2): c1 = img1.getpixel((x, y)) c2 = img2.getpixel((x, y)) result += distances[(c1, c2)] return result # d = dithered version of resized (peacock image, RGB color) d = pattern_dither(resized, PICO_RGB[:16], amount=1) # s = nearest-color image s = Image.new(size=d.size, mode='P', color=1) s.putpalette([c for rgb in PICO_RGB[:16] for c in rgb]) def solid_cost(img, xy1, xy2, color): """Returns cost of approximating a rectangular region with a solid color""" x1, y1 = xy1 x2, y2 = xy2 result = 0.0 for y in range(y1, y2): for x in range(x1, x2): p = img.getpixel((x, y)) result += distances[(color, p)] return result # Downsample the dithered image with a given size of rectangles skip = 2 for y in range(0, 128, skip): for x in range(0, 128, skip): _, i = min( (solid_cost(d, (x,y), (x+skip,y+skip), c), c) for c in range(16) ) for x2 in range(x, x + skip): for y2 in range(y, y + skip): s.putpixel((x2,y2), i) # s.show()