Создаем изображения для NFT с помощью python (1 часть)
Read Time:2 Minute, 34 Second

Создаем изображения для NFT с помощью python (1 часть)

Данная серия статей посвящена NFT, их созданию с точки зрения больших коллекций. В данной статье мы напишем простой генератор изображений на языке программирования Python. Я использую IDE VSCode и плагин notebook для набросков вроде этого.

Для работы с изображениями есть простенькая бибилиотека Pillow с которой мы и будем работать.

Первым делом создадим окружение, это не обязательный шаг, но крайне рекомендуемый и активируем его

python3 -m venv .venv
source .venv/bin/activate

Установим необходимые для работы пакеты для работы

pip3 install pillow numpy

Создаим файл generate.py и запишем следующий код:

from PIL import Image
import os
import random
import math
import numpy as np

# Функция нормализации блока мозаики
def getFixBoxSize(a, b):
    for i in range(0, b+1)[::-1]:
        if a % i == 0:
            return i

# Размер входящего изображения
in_w, in_h = (500,500)
# Размер исходящего изображения
out_w, out_h = (500,500)
# Размер блока мозаики
b_w, b_h = (100,50)
# Кол-во исходных изображений
use_src_images = 10

# Загружаем список изображений из директории
tmp_images = os.listdir("./img")

# Перемешиваем список
tmp_images = sorted(tmp_images, key=lambda A: random.random())

# Оставляем нужное кол-во изображений
if len(tmp_images) > use_src_images:
    path_images = [tmp_images[x] for x in range(0, use_src_images)]

# Загружаем изображения
for img in path_images:
    images.append(Image.open(f"./img/{img}").resize((in_w,in_h)))

# Создаем новый холст
mosaic = Image.new("RGB", (in_w, in_h), tuple(np.random.choice(range(256), size=3)))

print(f"Source Images: " + ", ".join(path_images))
print(f"IN size image: {in_w}x{in_h}")
print(f"Out size image: {out_w}x{out_h}")
print(f"Block size image: {b_w}x{b_h}")

b_w = getFixBoxSize(in_w, b_w)
b_h = getFixBoxSize(in_h, b_h)

print(f"Block FIX size image: {b_w}x{b_h}")
cols, rows = (math.ceil(in_w / b_w), math.ceil(in_h/b_h))
print(f"rows: {rows}")
print(f"cols: {cols}")

# формируем мозаику в виде матрицы
block_lines = [sorted([x2 for x2 in range(0,cols)], key=lambda A: random.random()) for x in range(0, rows)]

print("                 MATRIX")
print("\n".join(str(x) for x in block_lines))

# Формируем в цикле наши блоки из исходных изображений
for row in range(0, rows):
    for col in range(0, cols):
        rand = random.randrange(0 , len(images))
        num = block_lines[row].pop(0)
        quad = (b_w * num, b_h * row, b_w * num + b_w, b_h * row + b_h)
        quadimg = images[rand].crop(quad)
        mosaic.paste(quadimg, (b_w * num, b_h * row, b_w * num + b_w, b_h * row + b_h), quadimg)

# Изменяем размер исходящего изображения
mosaic.resize((out_w, out_h))

# Выводим изображение
mosaic.show()

Как видите, код получился очень простым, благодаря параметрам объявленным в самом начале, мы можешь изменять размерность блоков тем самым формируя новые стили генерации.

В следующей статье, мы перепишем данный пример и добавим генерацию нескольких изображений в коллаж, генерацию гиф анимации и что нибудь еще 🙂