Упс, я только что заметил, что вы пометили PHP, а не Python - извините! Сейчас я оставлю это в качестве ссылки и, возможно, сделаю версию PHP в другой день.
У меня была быстрая попытка, и она работает достаточно хорошо:
#!/usr/bin/env python3
import numpy
import random
import math
import sys
from PIL import Image
def crystallize(im, cnt):
# Make output image same size
res = np.zeros_like(im)
h, w = im.shape[:2]
# Generate some randomly placed crystal centres
nx = np.random.randint(0,w,cnt,dtype=np.uint16)
ny = np.random.randint(0,h,cnt,dtype=np.uint16)
# Pick up colours at those locations from source image
sRGB = []
for i in range(cnt):
sRGB.append(im[ny[i],nx[i]])
# Iterate over image
for y in range(h):
for x in range(w):
# Find nearest crystal centre...
dmin = sys.float_info.max
for i in range(cnt):
d = (y-ny[i])*(y-ny[i]) + (x-nx[i])*(x-nx[i])
if d < dmin:
dmin = d
j = i
# ... and copy colour of original image to result
res[y,x,:] = sRGB[j]
return res
# Open image, crystallize and save
im = Image.open('duck.jpg')
res = crystallize(np.array(im),200)
Image.fromarray(res).save('result.png')
Оказывается так:
![enter image description here](https://i.stack.imgur.com/CQBcA.jpg)
в это:
![enter image description here](https://i.stack.imgur.com/ISKXI.png)
или это, если вы идете за 500 кристаллов:
![enter image description here](https://i.stack.imgur.com/MVlbT.png)
Скорость, вероятно, можно улучшить, уменьшив до 256 цветов и поместив изображение в палитру, найдя для каждого ближайший цвет, а затем просто просматривая их в LUT. Может быть, работа на черный день ...
Ключевые слова : Python, вороной, кристалл, кристаллизация, Photoshop, фильтр, изображение, обработка изображений, Numpy, PIL, Pillow.