起因
看到網上的像素圖片,感覺蠻有趣的,就打算用python一些PIL類庫寫一個。
實現思路
把一張圖片分成多個塊,每個塊的顏色都等於這個色塊中顏色最多的顏色,如下圖。
這個圖取2×2的像素爲塊的大小,把快中顏色與每個顏色出現的數量存放到字典裏,取最大的顏色,填充整個塊。
具體實現
from PIL import Image
def init():
# 設置每個像素區塊的大小
block_size = 75
img = Image.open("a.jpg")
# 獲取圖片的寬高
width, height = img.size
# 獲取像素點對應RGB顏色值,可以改變img_array中的值來改變顏色值
img_array = img.load()
# 爲了處理最後的區塊,加了一次循環
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):
# 如果是最後一次循環,則x座標等於width - 1
if x == max_width - max_width % block_size - 1:
x = width - 1
# 如果是最後一次循環,則x座標等於height - 1
if y == max_height - max_height % block_size - 1:
y = height - 1
# 改變每個區塊的顏色值
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座標 x:
:param y座標 y:
:param 區塊大小 black_size:
:param 可操作圖片數組 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())]
# 將區塊內所有的顏色值設置爲顏色最多的顏色
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()
效果對比
總結
開源地址https://github.com/MasakiOvO/...
還有很多改進的地方,比如取色值的算法上,應該有更好的解決方法,應該用多進程來實現,這樣程序速度會快很多。OvO