В данной статье я покажу и расскажу, как можно сгенерировать аватарки как на Github.
Результат генерации для ника "test1"Для начала нужно понять, как устроена аватарка с Github'а. На первый взгляд, это просто случайный набор закрашенных квадратов (далее, блоков) в удачном порядке на сером фоне.
Сколько квадратов в аватаркеВ каждой аватарке 12 на 12 блоков.
Случайная автарка с просторов GithubВзглянув на следующую картинку, думаю, вы поняли что изображения симметричны, поэтому будем генерировать матрицу блоков 6 на 12, а затем отразим и сконкатенируем две матрицы, получим матрицу 12 на 12.
Ну что ж, похоже, пора кодировать. Я буду делать это на python.
Подключим библиотеки
from PIL import ImageDraw, Imageimport numpy as npimport hashlib
Инициализируем переменные
background_color = '#f2f1f2's = 'test1'
Получаемнаборпсевдослучайныхбайт. Я буду использовать хеш-функцию для того, чтобы получать картинки от конкретной строки, так результат получится интереснее.
bytes=hashlib.md5(s.encode('utf-8')).digest()
Получаемцветизхеша
main_color=bytes[:3]main_color=tuple(channel//2+128forchannelinmain_color)#rgb
Генерируемматрицузаполненияблоков, для этого берем следующие байты. Так как матрица 6 на 12, а информации на каждый блок у нас один бит, то нам понадобится:
#матрица блоков6на12need_color=np.array([bit=='1'forbyteinbytes[3:3+9]forbitinbin(byte)[2:].zfill(8)]).reshape(6,12)#получаемматрицу12на12 сконкатенировав оригинальную и отраженную матрицуneed_color=np.concatenate((need_color,need_color[::-1]),axis=0)
Рисуемизображенияпоматрицезаполнения
img_size = (avatar_size, avatar_size)block_size = avatar_size // 12 # размер квадратаimg = Image.new('RGB', img_size, background_color)draw = ImageDraw.Draw(img)for x in range(avatar_size): for y in range(avatar_size): need_to_paint = need_color[x // block_size, y // block_size] if need_to_paint: draw.point((x, y), main_color)
Отобразим то, что получилось
img.show()
И хоба
РезультатХммм, что-то не то. Ах, да, забыл, самые крайние блоки всегда не цветные.
Исправим это, добавив рамку из пустых блоков.
for i in range(12): need_color[0, i] = 0 need_color[11, i] = 0 need_color[i, 0] = 0 need_color[i, 11] = 0
Вуаля. Давайте теперь посмотрим на сгенерированные аватарки для других никнеймов.
test2test3test4test5И напоследок, специально для хабра.
habrufoНа этом все. Спасибо тем, кто дочитал, а тех, кто хочет эксперементировать, отправляю в свой репозиторий со всем кодом.