Рубрики
Без рубрики

Как создать генеративное искусство менее чем за 100 строк кода

Автор оригинала: FreeCodeCapm Team.

Эриком Дэвидсон

Генеративное искусство, как и любая тема программирования, может быть запугиваться, если вы никогда не пробовали его раньше. Я всегда был заинтересован в этом, потому что я люблю находить новые способы, которые программирование может быть использовано творчески. Кроме того, я думаю, что любой может оценить концепцию художественных работ, которые буквально создают себя.

Что такое генеративное искусство?

Генеративное искусство является выходом системы, которая делает свои собственные решения о части, а не человека. Система может быть такой простой, как одна программа Python, пока она имеет правила и какой-то аспект случайность.

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

Игра Жизни Является известным набором четырех простых правил, определяющих «рождение» и «смерть» каждой клетки в системе. Каждый из правил играет роль в продвижении системы через каждое поколение. Хотя правила простые и легко понимать, сложные шаблоны быстро начнут возникать и в конечном итоге формировать увлекательные результаты.

Правила могут быть ответственны за создание фундамента чего-то интересного, но даже что-то как увлекательное, как игра в жизни Конвея, является предсказуемым. Поскольку четыре правила являются определяющими факторами для каждого поколения, способ получения непредвиденных результатов – ввести рандомизацию в исходном состоянии клеток. Начиная с случайной матрицы сделает каждое исполнение уникальным без необходимости менять правила.

Лучшими примерами генеративного искусства являются те, которые находят комбинацию предсказуемости и случайности, чтобы создать что-то интересное, которое также статистически Иррепрокатный Отказ

Почему вы должны попробовать это?

Не все боковые проекты созданы равными, и генеративное искусство может быть не то, что вы склонны проводить время. Если вы решите работать над проектом, то вы можете ожидать, что эти преимущества:

  • Опыт – Генеративное искусство – это просто еще одна возможность отточить некоторые новые и старые навыки. Он может служить шлюзом для практикующих концепций, таких как алгоритмы, структуры данных и даже новые языки.
  • Ощутимые результаты – В мире программирования мы редко увидимся, чтобы какая-то физическая вещь выходит из наших усилий, или, по крайней мере, я не. Прямо сейчас у меня есть несколько плакатов в моей гостиной, где отображаются отпечатки моего генеративного искусства, и я люблю, что программирование несет ответственность за это.
  • Привлекательные проекты – У нас был опыт объяснения личного проекта для кого-то, возможно, даже во время интервью, без легкого способа передать усилия и результаты проекта. Генеративное искусство говорит само по себе, и большинство ваших творений будут впечатлены, даже если они не могут полностью понять методы.

Где вы должны начать?

Начало работы с генеративным искусством – это тот же процесс, что и любой проект, самый важный шаг – придумать идею или найти ее для создания. Как только у вас есть цель, то вы можете начать работать над технологией, необходимой для этого.

Большинство моих генеративных художественных проектов были достигнуты в Python. Это довольно легкий язык, чтобы привыкнуть, и у него есть некоторые невероятные пакеты, доступные, чтобы помочь с манипулированием изображений, такими как Подушка Отказ

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

Спрайтный генератор

Этот проект начался, когда я увидел сообщение, демонстрирующую генератор спрайта, написанного в JavaScript. Программа создала 5×5 Pixel Art Sprites с некоторыми параметрами случайных цветов, и его вывод напоминал разноцветные пространственные захватчики.

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

Вот взгляд на два разных выхода из решения, с которым я закончил:

Эти два изображения вообще не напоминают друг друга, но они оба результаты одной и той же системы. Не упоминать, из-за сложности изображения и случайность Из генерации спрайта существует чрезвычайно высокая вероятность того, что даже с теми же аргументами эти изображения будут навсегда быть одним из видов. Я люблю это.

Среда

Если вы хотите начать играть с генератором спрайта, есть небольшая работа основа, которая должна быть сделана первой.

Настройка правильной среды с Python может быть сложно. Если вы не работали с Python раньше, вам, вероятно, понадобится Скачать Python 2.7.10. Я изначально имел проблемы на создании окружающей среды, поэтому, если вы начнете бегать в проблемы, вы можете делать то, что я сделал и посмотрел на Виртуальные среды Отказ Последнее, но не менее важно, убедитесь, что у вас есть Подушка установлен также.

Как только у вас установлена среда, вы можете скопировать мой код в файл с расширением .py и выполнить со следующей командой:

python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]

Например, команда для создания первой матрицы спрайтов сверху будет:

python spritething.py 7 30 1900

Код

import PIL, random, sysfrom PIL import Image, ImageDraw
origDimension = 1500
r = lambda: random.randint(50,215)rc = lambda: (r(), r(), r())
listSym = []
def create_square(border, draw, randColor, element, size):  if (element == int(size/2)):    draw.rectangle(border, randColor)  elif (len(listSym) == element+1):    draw.rectangle(border,listSym.pop())  else:    listSym.append(randColor)    draw.rectangle(border, randColor)
def create_invader(border, draw, size):  x0, y0, x1, y1 = border  squareSize = (x1-x0)/size  randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)]  i = 1
  for y in range(0, size):    i *= -1    element = 0    for x in range(0, size):      topLeftX = x*squareSize + x0      topLeftY = y*squareSize + y0      botRightX = topLeftX + squareSize      botRightY = topLeftY + squareSize
      create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size)      if (element == int(size/2) or element == 0):        i *= -1;      element += i
def main(size, invaders, imgSize):  origDimension = imgSize  origImage = Image.new('RGB', (origDimension, origDimension))  draw = ImageDraw.Draw(origImage)
  invaderSize = origDimension/invaders  padding = invaderSize/size
  for x in range(0, invaders):    for y in range(0, invaders):      topLeftX = x*invaderSize + padding/2      topLeftY = y*invaderSize + padding/2      botRightX = topLeftX + invaderSize - padding      botRightY = topLeftY + invaderSize - padding
      create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size)
  origImage.save("Examples/Example-"+str(size)+"x"+str(size)+"-"+str(invaders)+"-"+str(imgSize)+".jpg")
if __name__ == "__main__":  main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))

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

Главная Функция начинается, создавая исходное изображение и определение размера спрайтов. Два для Петли несут ответственность за определение границы для каждого спрайта, в основном разделяя размеры изображения по количеству запрошенных спрайтов. Эти значения используются для определения координат для каждого.

Давайте игнорируем прокладку и посмотрите на изображение ниже. Представьте, что каждый из четырех квадратов представляет собой спрайт с размером 1. Граница, которая передается следующей функции, относится к верхней части левой и нижней правой координаты. Таким образом, кортеж для верхнего левого спрайта будет (0,0,1,1), тогда как кортеж для правого правила (1,0,2,1). Они будут использоваться в качестве измерений и координат базы для квадратов каждого спрайта.

Функция create_invader Определяет границу для каждого квадрата в спрайт. Тот же процесс определения границы применяется здесь и представлен ниже, только вместо полного изображения мы используем заранее определенную границу для работы внутри. Эти окончательные координаты для каждого квадрата будут использоваться в следующей функции, чтобы фактически нарисовать спрайт.

Чтобы определить цвет, простой массив трех случайных кортежей RGB и три чернокожих используются для моделирования натянутой 50%. Функции лямбда вблизи верхней части кода несут ответственность за генерацию значений RGB.

Настоящая хитрость этой функции создает симметрию. Каждый квадрат в паре со значением элемента. На рисунке ниже вы можете увидеть значения элементов, когда они достигают центра, а затем уменьшаются. Квадраты с соответствующими значениями элементов нарисованы с тем же цветом.

Как create_square Получает свои параметры от create_invader , он использует очередь и значения элементов, прежде чем для обеспечения симметрии. Первое вхождение значений у их цветов нажата на очередь, и зеркальные квадраты выключают цвета.

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

Заключение

Генеративное искусство требует времени, чтобы полностью оценить, но оно того стоит. Я люблю быть способным комбинировать программирование с более традиционным визуальным, и я определенно многому научился в каждом из моих проектов.

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

Спасибо за чтение!