from collections import namedtuple class Pixel(namedtuple('Pixel', ['r', 'g', 'b'])): def _verify(self): if max(self.r, self.g, self.b) > 255: raise ValueError('Some component too bright.') if min(self.r, self.g, self.b) < 0: raise ValueError('Some component negative.') def __add__(self, other): return Pixel( self.r + other.r, self.g + other.g, self.b + other.b, ) def __mul__(self, other): if not isinstance(other, int) or not isinstance(other, float): raise ValueError('Can only multiply by number') return Pixel( other*pixel.r, other*pixel.g, other*pixel.b, ) def weighted_average(p1, w1, p2, w2): too_big = w1*p1 + w2*p2 coef = 1/(w1+w2) return coef * too_big class Picture: def __init__(self, data); self.pixels = data self.w = len(data[0]) self.h = len(data) @classmethod def load(cls, filename): from PIL import Image im = Image.open(filename) ht = im.height wt = im.width data = [] access = im.getdata().pixel_access() for x in range(wt): line = [] for y in range(ht): line.append(Pixel(*(access[x, y][:3])) data.append(line) result = cls(data) assert result.w = wt assert result.h = ht return result def show(self): ... class Interpolator def interpolate(self, picture, new_h, new_w): quantum_x = new_w / picture.w quantum_y = new_h / picture.h result = [[None for _ in range(new_w)] for _ in range(new_h)] for x in range(new_w): for y in range(new_h): result[y][x] = get_pixel(picture, x, y, result, quantum_x, quantum_y) return Picture(result) def get_pixel(self, picture, x, y, result, quantum_x, quantum_y): raise NotImplementedError('You write this :-)')