Автор оригинала: 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 , он использует очередь и значения элементов, прежде чем для обеспечения симметрии. Первое вхождение значений у их цветов нажата на очередь, и зеркальные квадраты выключают цвета.
Я понимаю, насколько трудно прочитать и понять чужое решение для проблемы, и шероховатость кода, безусловно, не помогает со своей сложностью, но, надеюсь, вы получите довольно хорошую идею для того, как она работает. В конечном итоге было бы невероятно, если вы можете вообще ловить свой код и выяснить совершенно разное решение.
Заключение
Генеративное искусство требует времени, чтобы полностью оценить, но оно того стоит. Я люблю быть способным комбинировать программирование с более традиционным визуальным, и я определенно многому научился в каждом из моих проектов.
В целом, возможно, могут быть более полезные проекты, чтобы преследовать и генеративное искусство, возможно, не может быть чем-то, с кем вам нужен опыт, но это тонна веселья, и вы никогда не знаете, как это может отделить вас от толпы.
Спасибо за чтение!