“PK creative Spring Festival, I am participating in the” Spring Festival Creative submission contest “, please see: Spring Festival Creative Submission Contest”
· Pixelated images celebrating the Year of the Tiger using Python
1. Show the effect
2. Split the steps
2.1 Understanding Pixels
In our lives, we often hear that the resolution of a certain electronic device is 2K, or 4K and higher. And this among them 2K, 4K refers to what on earth?
2K and 4K are both a description of the resolution of an electronic product. 2K refers to 1920 pixels in the horizontal direction and 1080 pixels in the vertical direction. 4K refers to 3840 pixels in the horizontal direction and 2160 pixels in the vertical direction of the electronic product.
The electronic image is also composed of pixels in the horizontal direction and pixels in the vertical direction one by one. When we display the electronic image on electronic products, if the image is magnified by more than 100%, the larger the amplification ratio, the more blurred the image will be. As shown below:
2.2 Understand the pixelated style
Pixelated style is commonly seen in early video games, such as Dinosaur Kombat, King of Fighters, Street Fighter, etc. Early electronic products do not have the resolution of 2K and 4K as now, so they can only provide more images for players in a limited resolution. As shown below:
2.3 Idea of pixelation effect
At this point, we have to think about the question, how do we pixelate the image without changing the resolution of the image? Since the resolution cannot be changed, that is, the number of pixels in the horizontal and vertical directions of the image remains the same. Under the condition that the number remains unchanged, we can divide the image into blocks one by one, and set the color of all pixels in this block to the color of pixels with the most same color in this block, so as to achieve pixelation.
2.4 Achieve image pixelation effect
Against 2.4.1 install Pillow
Pillow is a module in Python dedicated to image processing, and everything we do next is based on the various functions provided in this module. From the command line window, we enter the following statement to install this module.
pip install pillow
Copy the code
2.4.2 Import the image processing module in PIL
from PIL import Image
Copy the code
2.4.3 Write a function to modify the color of pixels in an image
Modify a pixel of the image
# x represents the horizontal position of the pixel, y represents the vertical position of the pixel, color represents the color of the pixel, and image represents the picture
def putPixel(x, y, color, image) :
image.putpixel((x, y), color)
Copy the code
2.4.4 Write a function to modify the color of all pixels in a certain block of the image
# Change the color of all pixels in a block of the image
# startX indicates the horizontal position of the block, startY indicates the vertical position of the block, blockSize indicates the blockSize, and image indicates the image
def handleBlockPixel(startX, startY, blockSize, image) :
rgbList = []
for i in range(startX, startX + blockSize):
for j in range(startY, startY + blockSize):
rgbList.append(image.getpixel((startX, startY)))
color = max(rgbList, key=rgbList.count) Get the color of the pixel that appears most often
for i in range(startX, startX + blockSize):
for j in range(startY, startY + blockSize):
putPixel(i, j, color, image)
Copy the code
2.4.5 Write functions to determine whether image boundary pixels need to be processed
The reason why we need to write a function to determine whether to process image boundary pixels is that we used square blocks to change the color of all pixels in a certain block at the beginning. Using square blocks can better realize image pixelation, as shown in the following figure:
In this figure, purple is the image pixel to be processed, red is the image pixel to be processed, orange is the pixel where the initial horizontal and vertical coordinates of the processed image block are located, and blue is the image boundary pixel that has been processed
In above, if the level of the image pixels and the number of vertical pixels is not 1 to 1, then there will be an image pixel cannot be pixelated, if the level of the image pixels for five (5), vertical pixels for four, and we set the size of the block of 4 (level for four pixels, vertical pixels to 4), Then the last column of pixels in the image cannot be processed.
Similarly, if the image has 5 horizontal pixels and 4 vertical pixels, and we set the block size to 4 (4 horizontal pixels and 5 vertical pixels), then the last line of the image cannot be processed.
Therefore, we need to determine whether unprocessed image boundary pixels need to exist.
# Determine whether there are unprocessed image boundary pixels
# blockSize indicates the blockSize and image indicates the image
def shouldHandleOtherWidthAndHeight(blockSize, image) :
width, height = image.size
shouldHandleOtherWidth = False
shouldHandleOtherHeight = False
ifwidth % blockSize ! =0:
shouldHandleOtherWidth = True
ifheight % blockSize ! =0:
shouldHandleOtherHeight = True
return shouldHandleOtherWidth, shouldHandleOtherHeight
Copy the code
So how to deal with unprocessed image boundary pixels?
For the unprocessed image boundary pixel, we can calculate the initial horizontal coordinate and initial vertical coordinate of the block closest to the boundary pixel, and modify the color of all pixel points in this block in the image.
If the unprocessed column pixels in the image are processed, the initial horizontal coordinates of the block of the image to be processed will not change, and the initial vertical coordinates will change. As we see in the image above, the orange pixels are the pixels where the initial horizontal and vertical coordinates of the processing image block are located.
If the unprocessed row pixels in the image are processed, the initial horizontal coordinates of the block of the image to be processed will change, and the initial vertical coordinates will remain unchanged. As we see in the image above, the orange pixels are the pixels where the initial horizontal and vertical coordinates of the processing image block are located.
3. Complete code (based on Python3)
from PIL import Image
Modify a pixel of the image
# x represents the horizontal position of the pixel, y represents the vertical position of the pixel, color represents the color of the pixel, and image represents the picture
def putPixel(x, y, color, image) :
image.putpixel((x, y), color)
Determine whether there are unprocessed image pixels
# blockSize indicates the blockSize and image indicates the image
def shouldHandleOtherWidthAndHeight(blockSize, image) :
width, height = image.size
shouldHandleOtherWidth = False
shouldHandleOtherHeight = False
ifwidth % blockSize ! =0:
shouldHandleOtherWidth = True
ifheight % blockSize ! =0:
shouldHandleOtherHeight = True
return shouldHandleOtherWidth, shouldHandleOtherHeight
# Change the color of all pixels in a block of the image
# startX indicates the horizontal position of the block, startY indicates the vertical position of the block, blockSize indicates the blockSize, and image indicates the image
def handleBlockPixel(startX, startY, blockSize, image) :
rgbList = []
for i in range(startX, startX + blockSize):
for j in range(startY, startY + blockSize):
rgbList.append(image.getpixel((startX, startY)))
color = max(rgbList, key=rgbList.count) Get the color of the pixel that appears most often
for i in range(startX, startX + blockSize):
for j in range(startY, startY + blockSize):
putPixel(i, j, color, image)
Image pixelation function
# imagePath specifies the imagePath and blockSize specifies the blockSize
def run(imagePath, blockSize) :
image = Image.open(imagePath)
width, height = image.size
shouldHandleOtherWidth, shouldHandleOtherHeight = shouldHandleOtherWidthAndHeight(blockSize, image)
# Calculate the number of blocks the image can hold
widthTimes = (int)(width / blockSize)
heightTimes = (int)(height / blockSize)
# Process image pixels within blocks
for i in range(0, widthTimes):
startX = i * blockSize
for j in range(0, heightTimes):
startY = j * blockSize
handleBlockPixel(startX, startY, blockSize, image)
# Process unprocessed image pixels
if (shouldHandleOtherHeight):
for i in range(0, heightTimes):
startY = i * blockSize
handleBlockPixel(width - blockSize, startY, blockSize, image)
if (shouldHandleOtherWidth):
for i in range(0, widthTimes):
startX = i * blockSize
handleBlockPixel(startX, height - blockSize, blockSize, image)
Save the pixelated image
image.save('result.jpg')
# main function
if __name__ == "__main__":
run("image.jpg".5)
Copy the code
Author: Toyo
Copyright notice: This article is an original article, shall not be reproduced without my permission.