I am doing a function that pixelates black and white images. The function must be called pixelate(img, (pixel_width, pixel_height), mode)
.
The parameter (pixel_width, pixel_height)
is a tuple which indicates the size of the resulting pixel values. the function must return a result in any event, even if they are higher than the image dimensions. If the image size is not a multiple of the pixel size,some of the resulting pixels will have a smaller size than (pixel_width, pixel_height)
. This smaller pixels will be located in the right and bottom edge of the image as shown in the examples below. In other words, the pixels always start from the top left corner of the image.
The parameter mode, is an string, 'min', 'max' or 'mean'. We will write 'mean', if we want to calculate the mean value of the area where a pixel of the new image is going to be. We will write 'max' if we want the brightest value or 'min' for the darkest. If the mean value has decimals, we will only use the integer part.
Now I have the program done, but I want to do it writing the shortest possible code, to use as little CPU memory and time as possible.
from PIL import Image
import numpy as np
def pixelate_mode(mode):
if mode == 'mean':
return np.mean
elif mode == 'min':
return min
elif mode == 'max':
return max
def pixelate(img, (pixel_width, pixel_height), mode):
width, height = img.size
W = 0
while W * pixel_width < width:
H = 0
while H * pixel_height < height:
l = []
for x in xrange(pixel_width * W, pixel_width * (W + 1)):
for y in xrange(pixel_height * H, pixel_height * (H + 1)):
if x < width and y < height:
l.append(img.getpixel((x, y)))
color = pixelate_mode(mode)(l)
for x in xrange(pixel_width * W, pixel_width * (W + 1)):
for y in xrange(pixel_height * H, pixel_height * (H + 1)):
if x < width and y < height:
img.putpixel((x, y), color)
H += 1
W += 1
return img
And these are some examples applying the program to this image: it has 200×200 pixels, and each square of the image is 10×10 pixels.
pixelate(img, (10, 10), 'mean')
, pixelate(img, (5, 5), 'max')
,
pixelate(img, (2, 2), 'min')
and pixelate(img, (1, 1), 'mean')
return the same image.
pixelate(img, (11, 11), 'mean')
returns this.