You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.1 KiB
Python

3 years ago
from collections import namedtuple
3 years ago
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,
)
3 years ago
def weighted_average(p1, w1, p2, w2):
too_big = w1*p1 + w2*p2
coef = 1/(w1+w2)
return coef * too_big
class Picture:
3 years ago
def __init__(self, data):
self.pixels = data
3 years ago
self.w = len(data[0])
self.h = len(data)
@classmethod
def load(cls, filename):
from PIL import Image
im = Image.open(filename)
3 years ago
im = im.convert('RGB')
3 years ago
ht = im.height
wt = im.width
data = []
access = im.getdata().pixel_access()
for y in range(ht):
3 years ago
line = []
for x in range(wt):
3 years ago
line.append(Pixel(*(access[x, y])))
3 years ago
data.append(line)
result = cls(data)
3 years ago
assert result.w == wt
assert result.h == ht
3 years ago
return result
def _to_pil(self):
# Create int iterable
# TODO: If this is slow, we should use a generator.
seq = []
for line in self.pixels:
for pix in line:
seq.extend(pix)
# bytes…
b = bytes(seq)
# PIL image
from PIL import Image
img = Image.frombytes('RGB', (self.w, self.h), b)
return img
def show(self):
img = self._to_pil()
img.show()
def save(self, filename):
img = self._to_pil()
img.save(filename)
3 years ago
class Interpolator:
def interpolate(self, picture, new_h, new_w):
3 years ago
quantum_x = picture.w / new_w
quantum_y = picture.h / new_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):
3 years ago
result[y][x] = self.get_pixel(picture, x*quantum_x, y*quantum_y, result, quantum_x, quantum_y)
3 years ago
return Picture(result)
def get_pixel(self, picture, x, y, result, quantum_x, quantum_y):
raise NotImplementedError('You write this :-)')