How to pixelate a square image to 256 big pixels with python?
Asked Answered
T

4

19

I need to find an way to reduce a square image to 256 big pixels with python, preferably with the matplotlib and pillow libraries.

Got any ideas ?

Though answered 6/11, 2017 at 18:23 Comment(2)
What are 'big pixels'? Do you just want to resize an image to 16x16 pixels?Burch
Resize it down to 16x16 using default interpolation, scale it back up to original size using nearest neighbour interpolation.Tella
T
39

Nine months pass and I can now cobble together some Python - per your original request on how to pixellate an image with Python and PIL/Pillow.

#!/usr/local/bin/python3
from PIL import Image

# Open image
img = Image.open("artistic-swirl.jpg")

# Resize smoothly down to 16x16 pixels
imgSmall = img.resize((16,16), resample=Image.Resampling.BILINEAR)

# Scale back up using NEAREST to original size
result = imgSmall.resize(img.size, Image.Resampling.NEAREST)

# Save
result.save('result.png')

Original Image

enter image description here

Result

enter image description here


If you take it down to 32x32 pixels (instead of 16x16) and then resize back up, you get:

enter image description here

Tella answered 26/7, 2018 at 21:36 Comment(1)
Just for fun if anyone likes pixelated images... bustle.com/articles/…Tella
T
7

Another option is to use PyPXL

Python script to pixelate images and video using K-Means clustering in the Lab colorspace. Video pixelating support multi-processing to achieve better performance.

Using the Paddington image as a source you can run:

python pypxl_image.py -s 16 16 paddington.png paddington_pixelated.png

Which gives this result

enter image description here

Of course if you wanted it to have 256 x 256 pixels rather than just 256 big pixels you could run

python pypxl_image.py -s 256 256 paddington.png paddington_pixelated.png

Which gives this result

enter image description here

Both results have a more retro 8-bit look to them compared to the other solutions, which might suit your needs.

Tournedos answered 24/10, 2018 at 10:45 Comment(0)
L
6

Here is my solution using sliding window

import numpy as np
import matplotlib.pyplot as plt

def pixelate_rgb(img, window):
    n, m, _ = img.shape
    n, m = n - n % window, m - m % window
    img1 = np.zeros((n, m, 3))
    for x in range(0, n, window):
        for y in range(0, m, window):
            img1[x:x+window,y:y+window] = img[x:x+window,y:y+window].mean(axis=(0,1))
    return img1

img = plt.imread('test.png')

fig, ax = plt.subplots(1, 4, figsize=(20,10))

ax[0].imshow(pixelate_rgb(img, 5))
ax[1].imshow(pixelate_rgb(img, 10))
ax[2].imshow(pixelate_rgb(img, 20))
ax[3].imshow(pixelate_rgb(img, 30))

# remove frames
[a.set_axis_off() for a in ax.flatten()]
plt.subplots_adjust(wspace=0.03, hspace=0)

enter image description here

The main idea is to slide a window of a certain size through the image and calculate the mean color for that area. Then replace the original pixels in that area with this color.

Another idea is to process grayscale images. Here we calculate the mean color of a grayscale image for a region, but now we replace the original pixels with white or black color depending on whether the mean exceeds a threshold:

def pixelate_bin(img, window, threshold):
    n, m = img.shape
    n, m = n - n % window, m - m % window
    img1 = np.zeros((n,m))
    for x in range(0, n, window):
        for y in range(0, m, window):
            if img[x:x+window,y:y+window].mean() > threshold:
                img1[x:x+window,y:y+window] = 1
    return img1

# convert image to grayscale
img = np.dot(plt.imread('test.png'), [0.299 , 0.587, 0.114])

fig, ax = plt.subplots(1, 3, figsize=(15,10))

plt.tight_layout()
ax[0].imshow(pixelate_bin(img, 5, .2), cmap='gray')
ax[1].imshow(pixelate_bin(img, 5, .3), cmap='gray')
ax[2].imshow(pixelate_bin(img, 5, .45), cmap='gray')

# remove frames
[a.set_axis_off() for a in ax.flatten()]
plt.subplots_adjust(wspace=0.03, hspace=0)

enter image description here

Live demo

Keep in mind: png has values between 0 and 1, whereas jpg between 0 and 255

Lydalyddite answered 28/8, 2020 at 3:32 Comment(0)
T
4

Sorry, I can't give you a Python solution, but I can show you the technique and the result, just using ImageMagick at the command-line:

Starting with this:

enter image description here

First, resize the image down to 16x16 pixels using normal cubic, or bilinear interpolation, then scale the image back up to its original size using "nearest neighbour" interpolation:

magick artistic-swirl.jpg -resize 16x16 -scale 500x500 result.png

enter image description here

Keywords:

Pixelate, pixellate, pixelated, pixellated, ImageMagick, command-line, commandline, image, image processing, nearest neighbour interpolation.

Tella answered 7/11, 2017 at 8:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.