Python uses 61 lines of code to realize picture pixelation

Keywords: Python github

cause

It's interesting to see the pixel pictures on the Internet, so I plan to write one with some PIL libraries of python.

Implementation ideas

Divide a picture into several blocks. The color of each block is equal to the color with the most colors in this color block, as shown in the following figure.

This image takes 2 × 2 pixels as the block size, stores the fast colors and the number of each color in the dictionary, takes the largest color, and fills the whole block.

Concrete realization

from PIL import Image

def init():
    # Set the size of each pixel block
    block_size = 75
    img = Image.open("a.jpg")
    # Get the width and height of the picture
    width, height = img.size
    # Get the RGB color value corresponding to the pixel. You can change the value in img? Array to change the color value
    img_array = img.load()
    # To process the last block, a loop is added
    max_width = width + block_size
    max_height = height + block_size
    for x in range(block_size - 1, max_width, block_size):
        for y in range(block_size - 1, max_height, block_size):
            # If it is the last cycle, the x coordinate is equal to width - 1
            if x == max_width - max_width % block_size - 1:
                x = width - 1
            # If it is the last cycle, the x coordinate is equal to height - 1
            if y == max_height - max_height % block_size - 1:
                y = height - 1
            # Change the color value of each block
            change_block(x, y, block_size, img_array)
            y += block_size
        x += block_size
    img.save(r'D:\python\pixel_image\awesome_copy.png')
    img.show()

"""
:param x coordinate x: 
:param y coordinate y: 
:param block size black_size: 
:param Actionable picture array img_array: 
"""
def change_block(x, y, black_size, img_array):

    color_dist = {}
    block_pos_list = []
    for pos_x in range(-black_size + 1, 1):
        for pos_y in range(-black_size + 1, 1):
            # todo print(x + pos_x,y + pos_y)
            block_pos_list.append([x + pos_x, y + pos_y])
    for pixel in block_pos_list:
        if not str(img_array[pixel[0], pixel[1]]) in color_dist.keys():
            color_dist[str(img_array[pixel[0], pixel[1]])] = 1
        else:
            color_dist[str(img_array[pixel[0], pixel[1]])] += 1
    # key-->value => value-->key
    new_dict = {v: k for k, v in color_dist.items()}
    max_color = new_dict[max(color_dist.values())]
    # Set all color values in the block to the color with the most colors
    for a in block_pos_list:
        img_array[a[0], a[1]] = tuple(list(map(int, max_color[1:len(max_color) - 1].split(","))))


def get_key(dict, value):
    return [k for k, v in dict.items() if v == value]


if __name__ == "__main__":
    init()

Effect contrast


summary

Open source address https://github.com/MasakiOvO/...
There are still many improvements, such as the color value algorithm, there should be a better solution, should be used to achieve multi process, so the program speed will be much faster. OvO

Posted by trp on Mon, 09 Dec 2019 09:46:43 -0800