Слёрм Universe - Python на примере Minecraft
Файлы
Практика 9
RGB - адаптивная цветовая модель. Служит для вывода изображения на экраны мониторов и другие электронные устройства. Представьте, что мы направили лучи красного, зелёного и синего цветов в одну точку на белой стене. В центре получится белое пятно, интенсивность цветов в этой точке достигает 100%. То есть в RGB один цвет представлен тремя числами:
  • Оттенок красного;
  • Оттенок зелёного;
  • Оттенок красного.

Таким образом мы можем записать цвета в кортежи, состоящие из 3-х чисел от 0 до 255. У меня есть готовый словарь, в котором разным цветам сопоставлены различные блоки в Minecraft разных оттенков:
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

COLORS = {
    (35, 0): (228, 228, 228),  # white wool
    (35, 8): (160, 167, 167),  # light gray wool
    (35, 7): (65, 65, 65),  # dark gray wool
    (35, 15): (24, 20, 20),  # black wool
    (35, 14): (158, 43, 39),  # red wool
    (35, 1): (234, 126, 53),  # orange wool
    (35, 4): (194, 181, 28),  # yellow wool
    (35, 5): (57, 186, 46),  # lime green wool
    (35, 3): (99, 135, 210),  # light blue wool
    (35, 9): (38, 113, 145),  # cyan wool
    (35, 11): (37, 49, 147),  # blue wool
    (35, 10): (126, 52, 191),  # purple wool
    (35, 2): (190, 73, 201),  # magenta wool
    (35, 6): (217, 129, 153),  # pink wool
    (35, 12): (86, 51, 28),  # brown wool
    (35, 13): (54, 75, 24),  # green wool

    (3, 0): (117, 84, 58),  # dirt

    (17, 2): (88, 70, 43),  # oak log

    (5, 0): (140, 114, 70),  # oak planks
    (5, 1,): (115, 85, 49),  # spruce planks
    (5, 2): (168, 90, 50),  # birch planks
    (5, 3): (160, 115, 81),  # jungle planks
    (5, 4): (168, 90, 50),  # acacia planks
    (5, 5): (67, 43, 20),  # dark oak planks

    (172, 0): (152, 94, 68),  # untreated terracotta

    (159, 0): (210, 178, 161),  # white terracotta
    (159, 1): (162, 84, 38),  # orange terracotta
    (159, 2): (150, 88, 109),  # magenta terracotta
    (159, 3): (113, 109, 138),  # light blue terracotta
    (159, 4): (186, 133, 35),  # yellow terracotta
    (159, 5): (104, 118, 53),  # lime terracotta
    (159, 6): (162, 78, 79),  # pink terracotta
    (159, 7): (58, 42, 36),  # gray terracotta
    (159, 8): (135, 107, 98),  # light gray terracotta
    (159, 9): (87, 91, 91),  # cyan terracotta
    (159, 10): (118, 70, 86),  # purple terracotta
    (159, 11): (74, 60, 91),  # blue terracotta
    (159, 12): (77, 51, 36),  # brown terracotta
    (159, 13): (76, 83, 42),  # green terracotta
    (159, 14): (143, 61, 47),  # red terracotta
    (159, 15): (37, 23, 16),  # black terracotta

    (251, 0): (207, 213, 214),  # white concrete
    (251, 1): (224, 97, 1),  # orange concrete
    (251, 2): (169, 48, 159),  # magenta concrete
    (251, 3): (36, 137, 199),  # light blue concrete
    (251, 4): (241, 175, 21),  # yellow concrete
    (251, 5): (94, 169, 24),  # lime concrete
    (251, 6): (214, 101, 143),  # pink concrete
    (251, 7): (55, 58, 62),  # gray concrete
    (251, 8): (125, 125, 115),  # light gray concrete
    (251, 9): (21, 119, 136),  # cyan concrete
    (251, 10): (100, 32, 156),  # purple concrete
    (251, 11): (45, 47, 143),  # blue concrete
    (251, 12): (96, 60, 32),  # brown concrete
    (251, 13): (73, 91, 36),  # green concrete
    (251, 14): (142, 33, 33),  # red concrete
    (251, 15): (8, 10, 15),  # black concrete

    (1, 6): (132, 135, 134),  # polished andesite
    (1, 2): (154, 107, 89),  # polished granite
    (1, 4): (193, 193, 195),  # polished diorite
    (168, 0): (99, 156, 151),  # prismarine
    (168, 2): (99, 172, 158),  # prismarine bricks
    (179, 2): (181, 98, 31),  # red sandstone
    (24, 2): (224, 214, 170),  # normal sandstone
    (201, 0): (170, 126, 170),  # purpur block
    (82, 0): (161, 166, 179),  # clay

    (18, 0): (33, 125, 22),  # oak leaves
    (89, 0): (128, 105, 63),  # glowstone
    (24, 0): (84, 84, 84),  # sandstone
    (87, 0): (98, 47, 46),  # netherrack
    (7, 0): (74, 74, 74),  # bedrock
    (41, 0): (220, 211, 72),  # goldblock
    (1, 0): (110, 110, 110),  # stone
    (45, 0): (127, 83, 71),  # bricks
    (42, 0): (196, 196, 196),  # ironblock
    (57, 0): (97, 196, 191),  # diamondblock
    (103, 0): (131, 134, 32)    # melon
}
Обратите внимание, что в качестве ключей элементов словаря у нас содержится кортежи с двумя числами. Да-да, кортежи тоже могут быть ключами. На уроке по словарям мы уже с вами изучили, что ключами может быть любой НЕИЗМЕНЯЕМЫЙ тип данных. Итак, в кортеже-ключе у нас содержатся ID-блока и его оттенок (например, голубая шерсть), а в кортеже-значении - три числа RGB-палитры.

Создадим функцию, которая будет принимать четыре аргумента. Это цвет RGB представленный тремя числами: красный, зелёный и синий и наш словарь с палитрой. В этой функции мы будем проверять к какому цвету в словаре максимально близок переданный оттенок. Например, мы хотим узнать к какому цвету ближе всего розовый. К красному или синему? Конечно же, к красному. И на основе полученного ближайшего цвета из словаря функция будет возвращать кортеж с двумя числами, записанный в его ключе - ID блока и цвет этого блока в Minecraft.
from math import sqrt
from mcpi.minecraft import Minecraft
mc = Minecraft.create()

COLORS = {
    (35, 0): (228, 228, 228),  # white wool
    (35, 8): (160, 167, 167),  # light gray wool
    (35, 7): (65, 65, 65),  # dark gray wool
    (35, 15): (24, 20, 20),  # black wool
    (35, 14): (158, 43, 39),  # red wool
    (35, 1): (234, 126, 53),  # orange wool
    (35, 4): (194, 181, 28),  # yellow wool
    (35, 5): (57, 186, 46),  # lime green wool
    (35, 3): (99, 135, 210),  # light blue wool
    (35, 9): (38, 113, 145),  # cyan wool
    (35, 11): (37, 49, 147),  # blue wool
    (35, 10): (126, 52, 191),  # purple wool
    (35, 2): (190, 73, 201),  # magenta wool
    (35, 6): (217, 129, 153),  # pink wool
    (35, 12): (86, 51, 28),  # brown wool
    (35, 13): (54, 75, 24),  # green wool

    (3, 0): (117, 84, 58),  # dirt

    (17, 2): (88, 70, 43),  # oak log

    (5, 0): (140, 114, 70),  # oak planks
    (5, 1,): (115, 85, 49),  # spruce planks
    (5, 2): (168, 90, 50),  # birch planks
    (5, 3): (160, 115, 81),  # jungle planks
    (5, 4): (168, 90, 50),  # acacia planks
    (5, 5): (67, 43, 20),  # dark oak planks

    (172, 0): (152, 94, 68),  # untreated terracotta

    (159, 0): (210, 178, 161),  # white terracotta
    (159, 1): (162, 84, 38),  # orange terracotta
    (159, 2): (150, 88, 109),  # magenta terracotta
    (159, 3): (113, 109, 138),  # light blue terracotta
    (159, 4): (186, 133, 35),  # yellow terracotta
    (159, 5): (104, 118, 53),  # lime terracotta
    (159, 6): (162, 78, 79),  # pink terracotta
    (159, 7): (58, 42, 36),  # gray terracotta
    (159, 8): (135, 107, 98),  # light gray terracotta
    (159, 9): (87, 91, 91),  # cyan terracotta
    (159, 10): (118, 70, 86),  # purple terracotta
    (159, 11): (74, 60, 91),  # blue terracotta
    (159, 12): (77, 51, 36),  # brown terracotta
    (159, 13): (76, 83, 42),  # green terracotta
    (159, 14): (143, 61, 47),  # red terracotta
    (159, 15): (37, 23, 16),  # black terracotta

    (251, 0): (207, 213, 214),  # white concrete
    (251, 1): (224, 97, 1),  # orange concrete
    (251, 2): (169, 48, 159),  # magenta concrete
    (251, 3): (36, 137, 199),  # light blue concrete
    (251, 4): (241, 175, 21),  # yellow concrete
    (251, 5): (94, 169, 24),  # lime concrete
    (251, 6): (214, 101, 143),  # pink concrete
    (251, 7): (55, 58, 62),  # gray concrete
    (251, 8): (125, 125, 115),  # light gray concrete
    (251, 9): (21, 119, 136),  # cyan concrete
    (251, 10): (100, 32, 156),  # purple concrete
    (251, 11): (45, 47, 143),  # blue concrete
    (251, 12): (96, 60, 32),  # brown concrete
    (251, 13): (73, 91, 36),  # green concrete
    (251, 14): (142, 33, 33),  # red concrete
    (251, 15): (8, 10, 15),  # black concrete

    (1, 6): (132, 135, 134),  # polished andesite
    (1, 2): (154, 107, 89),  # polished granite
    (1, 4): (193, 193, 195),  # polished diorite
    (168, 0): (99, 156, 151),  # prismarine
    (168, 2): (99, 172, 158),  # prismarine bricks
    (179, 2): (181, 98, 31),  # red sandstone
    (24, 2): (224, 214, 170),  # normal sandstone
    (201, 0): (170, 126, 170),  # purpur block
    (82, 0): (161, 166, 179),  # clay

    (18, 0): (33, 125, 22),  # oak leaves
    (89, 0): (128, 105, 63),  # glowstone
    (24, 0): (84, 84, 84),  # sandstone
    (87, 0): (98, 47, 46),  # netherrack
    (7, 0): (74, 74, 74),  # bedrock
    (41, 0): (220, 211, 72),  # goldblock
    (1, 0): (110, 110, 110),  # stone
    (45, 0): (127, 83, 71),  # bricks
    (42, 0): (196, 196, 196),  # ironblock
    (57, 0): (97, 196, 191),  # diamondblock
    (103, 0): (131, 134, 32)    # melon
}


def get_nearest_colored_block(red, green, blue, palette):
    nearest_color = None
    for color in palette:
        color_distance = sqrt((red - palette[color][0]) ** 2 + (green - palette[color][1]) ** 2 + (blue - palette[color][2]) ** 2)
        if nearest_color is None or color_distance < nearest_color[0]:
            nearest_color = [color_distance, color]
    return nearest_color[1]
  • В самом начале мы задаём имя функции и перечисляем какие аргументы она принимает;
  • После создаём переменную nearest_color, в которой будет записан ближайший ID блока в Minecraft и его оттенок к RGB-цвету, переданному в функцию;
  • Далее при помощи цикла FOR записываем в переменную color каждый отдельный ключ нашего словаря COLORS;
  • Раз цвет это три числа, то кто мешает представить, что это точки в пространстве и каждое значение это координата. Теперь, так как цвета это вектора - мы ищем между ними расстояние по школьной формуле "корень из суммы квадратов координат". Ну а дальше все просто: чем меньше расстояние, тем ближе цвет к нужному. Для получения корня мы импортируем и используем функцию sqrt из модуля math;
  • И теперь ЕСЛИ переменная nearest_color содержит значение None ИЛИ значение color_distance меньше предыдущего (то есть найден БОЛЕЕ ближайший цвет), ТО мы записываем в nearest_color обычный список с двумя элементами: число с расстоянием, полученный при помощи функции sqrt и кортеж с ID блока и его оттенком в Minecraft;
  • В конце функции мы возвращаем кортеж с ID блока и его оттенком в Minecraft, наиболее подходящий к RGB-оттенку, переданному в эту функцию.

Теперь давайте передадим в команду любую картинку или фотографию, сделаем её размером 64x64 пикселя, и преобразуем в RGBA. Чем отличается RGB от RGBA? Если в RGB мы записываем три числа для того, чтобы получить цвет, то в RGBA мы используем четыре числа. Четвёртое число называется "альфа-каналом" и отвечает за прозрачность. Альфа канал тоже может содержать число от 0 до 255. Чем ниже число, тем прозрачнее цвет.
from math import sqrt
from mcpi.minecraft import Minecraft
from PIL import Image
mc = Minecraft.create()

COLORS = {
    (35, 0): (228, 228, 228),  # white wool
    (35, 8): (160, 167, 167),  # light gray wool
    (35, 7): (65, 65, 65),  # dark gray wool
    (35, 15): (24, 20, 20),  # black wool
    (35, 14): (158, 43, 39),  # red wool
    (35, 1): (234, 126, 53),  # orange wool
    (35, 4): (194, 181, 28),  # yellow wool
    (35, 5): (57, 186, 46),  # lime green wool
    (35, 3): (99, 135, 210),  # light blue wool
    (35, 9): (38, 113, 145),  # cyan wool
    (35, 11): (37, 49, 147),  # blue wool
    (35, 10): (126, 52, 191),  # purple wool
    (35, 2): (190, 73, 201),  # magenta wool
    (35, 6): (217, 129, 153),  # pink wool
    (35, 12): (86, 51, 28),  # brown wool
    (35, 13): (54, 75, 24),  # green wool

    (3, 0): (117, 84, 58),  # dirt

    (17, 2): (88, 70, 43),  # oak log

    (5, 0): (140, 114, 70),  # oak planks
    (5, 1,): (115, 85, 49),  # spruce planks
    (5, 2): (168, 90, 50),  # birch planks
    (5, 3): (160, 115, 81),  # jungle planks
    (5, 4): (168, 90, 50),  # acacia planks
    (5, 5): (67, 43, 20),  # dark oak planks

    (172, 0): (152, 94, 68),  # untreated terracotta

    (159, 0): (210, 178, 161),  # white terracotta
    (159, 1): (162, 84, 38),  # orange terracotta
    (159, 2): (150, 88, 109),  # magenta terracotta
    (159, 3): (113, 109, 138),  # light blue terracotta
    (159, 4): (186, 133, 35),  # yellow terracotta
    (159, 5): (104, 118, 53),  # lime terracotta
    (159, 6): (162, 78, 79),  # pink terracotta
    (159, 7): (58, 42, 36),  # gray terracotta
    (159, 8): (135, 107, 98),  # light gray terracotta
    (159, 9): (87, 91, 91),  # cyan terracotta
    (159, 10): (118, 70, 86),  # purple terracotta
    (159, 11): (74, 60, 91),  # blue terracotta
    (159, 12): (77, 51, 36),  # brown terracotta
    (159, 13): (76, 83, 42),  # green terracotta
    (159, 14): (143, 61, 47),  # red terracotta
    (159, 15): (37, 23, 16),  # black terracotta

    (251, 0): (207, 213, 214),  # white concrete
    (251, 1): (224, 97, 1),  # orange concrete
    (251, 2): (169, 48, 159),  # magenta concrete
    (251, 3): (36, 137, 199),  # light blue concrete
    (251, 4): (241, 175, 21),  # yellow concrete
    (251, 5): (94, 169, 24),  # lime concrete
    (251, 6): (214, 101, 143),  # pink concrete
    (251, 7): (55, 58, 62),  # gray concrete
    (251, 8): (125, 125, 115),  # light gray concrete
    (251, 9): (21, 119, 136),  # cyan concrete
    (251, 10): (100, 32, 156),  # purple concrete
    (251, 11): (45, 47, 143),  # blue concrete
    (251, 12): (96, 60, 32),  # brown concrete
    (251, 13): (73, 91, 36),  # green concrete
    (251, 14): (142, 33, 33),  # red concrete
    (251, 15): (8, 10, 15),  # black concrete

    (1, 6): (132, 135, 134),  # polished andesite
    (1, 2): (154, 107, 89),  # polished granite
    (1, 4): (193, 193, 195),  # polished diorite
    (168, 0): (99, 156, 151),  # prismarine
    (168, 2): (99, 172, 158),  # prismarine bricks
    (179, 2): (181, 98, 31),  # red sandstone
    (24, 2): (224, 214, 170),  # normal sandstone
    (201, 0): (170, 126, 170),  # purpur block
    (82, 0): (161, 166, 179),  # clay

    (18, 0): (33, 125, 22),  # oak leaves
    (89, 0): (128, 105, 63),  # glowstone
    (24, 0): (84, 84, 84),  # sandstone
    (87, 0): (98, 47, 46),  # netherrack
    (7, 0): (74, 74, 74),  # bedrock
    (41, 0): (220, 211, 72),  # goldblock
    (1, 0): (110, 110, 110),  # stone
    (45, 0): (127, 83, 71),  # bricks
    (42, 0): (196, 196, 196),  # ironblock
    (57, 0): (97, 196, 191),  # diamondblock
    (103, 0): (131, 134, 32)    # melon
}


def get_nearest_colored_block(red, green, blue, palette):
    nearest_color = None
    for color in palette:
        color_distance = sqrt((red - palette[color][0]) ** 2 + (green - palette[color][1]) ** 2 + (blue - palette[color][2]) ** 2)
        if nearest_color is None or color_distance < nearest_color[0]:
            nearest_color = [color_distance, color]
    return nearest_color[1]


image_file = open("2021-06-14 13.48.38.jpg", "rb")
image = Image.open(image_file).resize((64, 64)).convert('RGBA')
x, y, z = mc.player.getPos()
  • Первым делом мы открываем картинку в режиме ЧТЕНИЯ и в бинарном (ДВОИЧНОМ) виде;
  • Далее в переменную image мы записываем сконвертированную картинку в RGBA размером 64x64 пикселя. Обратите внимание, что для этого мы использовали методы resize и convert. Но откуда они взялись? В стандартной библиотеки Python таких методов нет. Помните, мы уже говорили о том, что в Python множество внешних библиотек, которые мы можем с лёгкостью загружать? Для этого используется менеджер пакетов (библиотек) pip. Он позволяет загружать из Интернета необходимые нам библиотеки из огромного множество. Однако, для корректной работы pip, его нужно обновить. Нажмите в правом нижнем углу окна с PyCharm на надпись "Python", а после - на кнопку "Interpreter Settings":
В появившемся окне дважды кликаем левой кнопкой мыши на строчку с названием pip:
Далее ставим галочку на против графы "Specify version", из выпадающего списка выбираем последнюю версию и нажимаем кнопку Install Package. Таким образом pip будет обновлён:
Далее в окне с установленными пакетами нажимаем кнопку "+":
В появившемся окне в графу поиска записываем "Pillow". Выделяем левой кнопкой мыши найденную в списке библиотеку Pillow и нажимаем на кнопку Install Package. Необходимая библиотека для работы с изображением установлена!
  • И в конце мы определяем координаты нашего игрока в переменных x, y, z.
from math import sqrt
from mcpi.minecraft import Minecraft
from PIL import Image
mc = Minecraft.create()

COLORS = {
    (35, 0): (228, 228, 228),  # white wool
    (35, 8): (160, 167, 167),  # light gray wool
    (35, 7): (65, 65, 65),  # dark gray wool
    (35, 15): (24, 20, 20),  # black wool
    (35, 14): (158, 43, 39),  # red wool
    (35, 1): (234, 126, 53),  # orange wool
    (35, 4): (194, 181, 28),  # yellow wool
    (35, 5): (57, 186, 46),  # lime green wool
    (35, 3): (99, 135, 210),  # light blue wool
    (35, 9): (38, 113, 145),  # cyan wool
    (35, 11): (37, 49, 147),  # blue wool
    (35, 10): (126, 52, 191),  # purple wool
    (35, 2): (190, 73, 201),  # magenta wool
    (35, 6): (217, 129, 153),  # pink wool
    (35, 12): (86, 51, 28),  # brown wool
    (35, 13): (54, 75, 24),  # green wool

    (3, 0): (117, 84, 58),  # dirt

    (17, 2): (88, 70, 43),  # oak log

    (5, 0): (140, 114, 70),  # oak planks
    (5, 1,): (115, 85, 49),  # spruce planks
    (5, 2): (168, 90, 50),  # birch planks
    (5, 3): (160, 115, 81),  # jungle planks
    (5, 4): (168, 90, 50),  # acacia planks
    (5, 5): (67, 43, 20),  # dark oak planks

    (172, 0): (152, 94, 68),  # untreated terracotta

    (159, 0): (210, 178, 161),  # white terracotta
    (159, 1): (162, 84, 38),  # orange terracotta
    (159, 2): (150, 88, 109),  # magenta terracotta
    (159, 3): (113, 109, 138),  # light blue terracotta
    (159, 4): (186, 133, 35),  # yellow terracotta
    (159, 5): (104, 118, 53),  # lime terracotta
    (159, 6): (162, 78, 79),  # pink terracotta
    (159, 7): (58, 42, 36),  # gray terracotta
    (159, 8): (135, 107, 98),  # light gray terracotta
    (159, 9): (87, 91, 91),  # cyan terracotta
    (159, 10): (118, 70, 86),  # purple terracotta
    (159, 11): (74, 60, 91),  # blue terracotta
    (159, 12): (77, 51, 36),  # brown terracotta
    (159, 13): (76, 83, 42),  # green terracotta
    (159, 14): (143, 61, 47),  # red terracotta
    (159, 15): (37, 23, 16),  # black terracotta

    (251, 0): (207, 213, 214),  # white concrete
    (251, 1): (224, 97, 1),  # orange concrete
    (251, 2): (169, 48, 159),  # magenta concrete
    (251, 3): (36, 137, 199),  # light blue concrete
    (251, 4): (241, 175, 21),  # yellow concrete
    (251, 5): (94, 169, 24),  # lime concrete
    (251, 6): (214, 101, 143),  # pink concrete
    (251, 7): (55, 58, 62),  # gray concrete
    (251, 8): (125, 125, 115),  # light gray concrete
    (251, 9): (21, 119, 136),  # cyan concrete
    (251, 10): (100, 32, 156),  # purple concrete
    (251, 11): (45, 47, 143),  # blue concrete
    (251, 12): (96, 60, 32),  # brown concrete
    (251, 13): (73, 91, 36),  # green concrete
    (251, 14): (142, 33, 33),  # red concrete
    (251, 15): (8, 10, 15),  # black concrete

    (1, 6): (132, 135, 134),  # polished andesite
    (1, 2): (154, 107, 89),  # polished granite
    (1, 4): (193, 193, 195),  # polished diorite
    (168, 0): (99, 156, 151),  # prismarine
    (168, 2): (99, 172, 158),  # prismarine bricks
    (179, 2): (181, 98, 31),  # red sandstone
    (24, 2): (224, 214, 170),  # normal sandstone
    (201, 0): (170, 126, 170),  # purpur block
    (82, 0): (161, 166, 179),  # clay

    (18, 0): (33, 125, 22),  # oak leaves
    (89, 0): (128, 105, 63),  # glowstone
    (24, 0): (84, 84, 84),  # sandstone
    (87, 0): (98, 47, 46),  # netherrack
    (7, 0): (74, 74, 74),  # bedrock
    (41, 0): (220, 211, 72),  # goldblock
    (1, 0): (110, 110, 110),  # stone
    (45, 0): (127, 83, 71),  # bricks
    (42, 0): (196, 196, 196),  # ironblock
    (57, 0): (97, 196, 191),  # diamondblock
    (103, 0): (131, 134, 32)    # melon
}


def get_nearest_colored_block(red, green, blue, palette):
    nearest_color = None
    for color in palette:
        color_distance = sqrt((red - palette[color][0]) ** 2 + (green - palette[color][1]) ** 2 + (blue - palette[color][2]) ** 2)
        if nearest_color is None or color_distance < nearest_color[0]:
            nearest_color = [color_distance, color]
    return nearest_color[1]


image_file = open("2021-06-14 13.48.38.jpg", "rb")
image = Image.open(image_file).resize((64, 64)).convert('RGBA')
x, y, z = mc.player.getPos()

for width in range(64):
    for height in range(64):
        red, green, blue, alpha = image.getpixel((63 - width, 63 - height))
        block_id, block_metatag = (0, 0) if alpha == 0 else get_nearest_colored_block(red, green, blue, COLORS)
        mc.setBlock(x + 10, y + height, z + width, block_id, block_metatag)
  • Строим фото-стену при помощи циклов FOR;
  • Далее определяем цвет и прозрачность КАЖДОГО ОТДЕЛЬНОГО пикселя картинки и записываем его в переменные red, green, blue, alpha;
  • В переменных block_id, block_metatag мы используем тернарный оператор. ЕСЛИ прозрачность пикселя равна нулю, ТО ID блока и его оттенок равны нулю, то есть получится блок с воздухом, А ИНАЧЕ мы определяем ближайший по цвету блок из Minecraft при помощи созданной нами функции get_nearest_colored_block();
  • И в конце мы возводим в Minecraft каждый пиксель в виде блока, наиболее подходящего ему по оттенку.