Каким бы случайным это ни казалось, это было на удивление приятно и весело. Да, я сидел и просто создал массивы Numpy с определенными значениями RGB для создания изображений мобов Minecraft размером 720x720 пикселей.

Начиная

Сначала импортируем необходимые библиотеки: numpy для создания массивов и управления ими, matplotlib для отображения и сохранения данных в виде файла изображения и модуль random (он использовался только для случайного выбора оттенков зеленого для лицо лианы).

import numpy as np
import matplotlib.pyplot as plt
import random

Инициализация массива Numpy

creeper = np.full((720,720,3), 255, dtype="uint8")

Здесь я использую Numpy для инициализации массива (720 пикселей по ширине и высоте и третье измерение для хранения цвета) со значением 255 и dtype как uint8, то есть 8. -битовое целое число без знака (0–255). Отображение массива в виде изображения с использованием pyplot.imshow() даст полностью белое изображение, поскольку оно заполнено значением 255.

Настройка цветов

Я составил список оттенков зеленого, которые мне нужны для лица лианы. Все эти цвета представлены в виде значений RGB (красный, зеленый, синий), каждое из которых хранит некоторое целое число в диапазоне 0–255 (вот почему мы используем dtype=”uint8").

greens = [[204, 255, 204], #lighter to darker shades of green
          [153, 255, 153],
          [102, 255, 102],
          [51, 255, 51], 
          [0, 255, 0], 
          [0, 204, 0], 
          [0, 153, 0], 
          [0, 102, 0]]

Заполнение цветов

Поскольку изображение имеет размер 720x720 пикселей, я решил разделить плоскость на квадраты по 90 пикселей, чтобы разделить все изображение в виде сетки 8x8. Это было сделано путем запуска двух циклов for с диапазоном 0–720 и шагом 90.

Для каждой итерации внутреннего цикла я выбирал случайный оттенок зеленого из списка greens с помощью функции random.choices(). Затем я использовал нарезку массива numpy, чтобы установить единичный блок изображения 90x90 со случайно выбранным цветом.

for i in range(0,720,90):
    for j in range(0,720,90):
        color = random.choices(greens, k=1)[0]
        creeper[i:i+90, j:j+90] = color

В результате изображение будет выглядеть примерно так:

Затем, чтобы заполнить черты лица, я просто получил положение каждой функции, умножив номер прямоугольника, который я хотел раскрасить, на значение 90. Например, для примера. на изображении выше, чтобы раскрасить второй последний квадрат в верхней строке (или позиции (0,6)), начальный индекс по строкам будет 0 * 90 = 0, а значение по столбцам будет 6 * 90 = 540. Конечный индекс будет зависеть от того, сколько блоков (строк и столбцов) мы хотим раскрасить.

creeper[90:270, 90:270] = [0, 0, 0] # right-eye
creeper[90:270, 450:630] = [0, 0, 0] # left-eye
creeper[270:360, 270:450] = [0, 0, 0] # nose
creeper[360:540, 180:540] = [0, 0, 0] # mouth
creeper[540:630, 180:270] = [0, 0, 0] # mouth bottom right trail
creeper[540:630, 450:540] = [0, 0, 0] # mouth bottom left trail

Вот и все. Теперь массив при отображении в виде изображения будет выглядеть так:

Довольно просто, правда? Я также сделал лицо эндермена, просто инициализировав массив черным (0, 0, 0) вместо белого (255, 255, 255).

enderman = np.full((720,720,3), 0, dtype="uint8")

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

purples = [[236, 116, 255], [204, 0, 204], [237, 140, 255]]

Затем я просто заполнил нужные поля в сетке нужными мне цветами.

enderman[360:450, 0:90] = enderman[360:450,630:720] = purples[0]
enderman[360:450, 90:180] = enderman[360:450,540:630] = purples[1]
enderman[360:450, 180:270] = enderman[360:450,450:540] = purples[2]

Конечный результат будет выглядеть так:

Вы можете легко объединить эти изображения по вертикали или горизонтали, используя numpy.vstack() или numpy.hstack().

collage = np.hstack((creeper, enderman))

Вы также можете сохранить изображение локально, используя pyplot.imsave().

plt.imsave("collage.jpg", collage)

Вот и все. Надеюсь, вам это показалось интересным. Мне определенно понравилось это делать, и, вероятно, в конечном итоге я буду изображать всех мобов одинаково хи-хи.

Спасибо :)