So erstellen Sie generative Kunst in weniger als 100 Codezeilen

Generative Kunst kann, wie jedes Programmierthema, einschüchternd sein, wenn Sie sie noch nie zuvor ausprobiert haben. Ich war schon immer daran interessiert, weil ich es liebe, neue Wege zu finden, wie Programmierung kreativ genutzt werden kann. Darüber hinaus denke ich, dass jeder das Konzept von Kunstwerken schätzen kann, die sich buchstäblich selbst erschaffen.

Was ist generative Kunst?

Generative Kunst ist das Ergebnis eines Systems, das seine eigenen Entscheidungen über das Stück trifft und nicht über einen Menschen. Das System könnte so einfach wie ein einzelnes Python-Programm sein, solange es Regeln und einen Aspekt der Zufälligkeit enthält.

Mit der Programmierung ist es ziemlich einfach, Regeln und Einschränkungen zu finden. Das sind alles bedingte Aussagen. Trotzdem kann es schwierig sein, Wege zu finden, um diese Regeln interessant zu machen.

Das Spiel des Lebens ist ein berühmter Satz von vier einfachen Regeln, die die „Geburt“ und den „Tod“ jeder Zelle im System bestimmen. Jede der Regeln spielt eine Rolle bei der Weiterentwicklung des Systems durch jede Generation. Obwohl die Regeln einfach und leicht zu verstehen sind, entstehen schnell komplexe Muster, die letztendlich faszinierende Ergebnisse liefern.

Regeln können dafür verantwortlich sein, die Grundlage für etwas Interessantes zu schaffen, aber selbst etwas so Aufregendes wie Conways Spiel des Lebens ist vorhersehbar. Da die vier Regeln die bestimmenden Faktoren für jede Generation sind, besteht die Möglichkeit, unvorhersehbare Ergebnisse zu erzielen, darin, eine Randomisierung im Startzustand der Zellen einzuführen. Wenn Sie mit einer Zufallsmatrix beginnen, wird jede Ausführung eindeutig, ohne dass die Regeln geändert werden müssen.

Die besten Beispiele für generative Kunst sind diejenigen, die eine Kombination aus Vorhersagbarkeit und Zufälligkeit finden, um etwas Interessantes zu schaffen, das auch statistisch nicht reproduzierbar ist .

Warum sollten Sie es versuchen?

Nicht alle Nebenprojekte sind gleich, und generative Kunst ist möglicherweise nicht etwas, für das Sie gerne Zeit aufwenden. Wenn Sie sich jedoch für ein Projekt entscheiden, können Sie folgende Vorteile erwarten:

  • Erfahrung - Generative Kunst ist nur eine weitere Gelegenheit, neue und alte Fähigkeiten zu verbessern. Es kann als Gateway zum Üben von Konzepten wie Algorithmen, Datenstrukturen und sogar neuen Sprachen dienen.
  • Greifbare Ergebnisse - In der Programmierwelt sehen wir selten etwas Physisches aus unseren Bemühungen, oder zumindest ich nicht. Im Moment habe ich ein paar Poster in meinem Wohnzimmer, auf denen Drucke meiner generativen Kunst zu sehen sind, und ich liebe es, dass die Programmierung dafür verantwortlich ist.
  • Attraktive Projekte - Wir haben alle die Erfahrung gemacht, jemandem ein persönliches Projekt zu erklären, möglicherweise sogar während eines Interviews, ohne auf einfache Weise den Aufwand und die Ergebnisse des Projekts zu vermitteln. Generative Kunst spricht für sich selbst und die meisten Menschen werden von Ihren Kreationen beeindruckt sein, auch wenn sie die Methoden nicht vollständig verstehen können.

Wo solltest du anfangen?

Der Einstieg in die generative Kunst ist der gleiche Prozess wie bei jedem anderen Projekt. Der wichtigste Schritt besteht darin, eine Idee zu entwickeln oder eine zu finden, auf der man aufbauen kann. Sobald Sie ein Ziel vor Augen haben, können Sie an der Technologie arbeiten, die erforderlich ist, um dieses Ziel zu erreichen.

Die meisten meiner generativen Kunstprojekte wurden in Python durchgeführt. Es ist eine ziemlich gewöhnungsbedürftige Sprache und es stehen einige unglaubliche Pakete zur Verfügung, die bei der Bildmanipulation helfen, wie z. B. Pillow.

Zum Glück müssen Sie nicht sehr weit nach einem Ausgangspunkt suchen, da ich unten einen Code bereitgestellt habe, mit dem Sie spielen können.

Sprite-Generator

Dieses Projekt begann, als ich einen Beitrag sah, in dem ein in Javascript geschriebener Sprite-Generator gezeigt wurde. Das Programm erstellte Kunst-Sprites mit 5 x 5 Pixeln und einigen zufälligen Farboptionen. Die Ausgabe ähnelte mehrfarbigen Space Invaders.

Ich wusste, dass ich die Bildmanipulation in Python üben wollte, also dachte ich mir, ich könnte einfach versuchen, dieses Konzept selbst neu zu erstellen. Außerdem dachte ich, ich könnte es erweitern, da das ursprüngliche Projekt in der Größe der Sprites so begrenzt war. Ich wollte nicht nur die Größe, sondern auch die Anzahl und sogar die Größe des Bildes angeben können.

Hier ist ein Blick auf zwei verschiedene Ausgaben der Lösung, die ich erhalten habe:

Diese beiden Bilder ähneln sich überhaupt nicht, aber sie sind beide das Ergebnis desselben Systems. Ganz zu schweigen von der Komplexität des Bildes und der Zufälligkeit der Sprite-Generation besteht eine extrem hohe Wahrscheinlichkeit, dass diese Bilder selbst mit denselben Argumenten für immer einzigartig sein werden. Ich liebe es.

Die Umgebung

Wenn Sie anfangen möchten, mit dem Sprite-Generator herumzuspielen, müssen Sie zuerst ein wenig Grundarbeit leisten.

Das Einrichten einer geeigneten Umgebung mit Python kann schwierig sein. Wenn Sie noch nicht mit Python gearbeitet haben, müssen Sie wahrscheinlich Python 2.7.10 herunterladen. Ich hatte anfangs Probleme beim Einrichten der Umgebung. Wenn Sie also auf Probleme stoßen, können Sie das tun, was ich getan habe, und sich virtuelle Umgebungen ansehen. Stellen Sie zu guter Letzt sicher, dass auch Pillow installiert ist.

Sobald Sie die Umgebung eingerichtet haben, können Sie meinen Code in eine Datei mit der Erweiterung .py kopieren und mit dem folgenden Befehl ausführen:

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

Der Befehl zum Erstellen der ersten Matrix von Sprites von oben lautet beispielsweise:

python spritething.py 7 30 1900

Der Code

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]))

Diese Lösung ist weit davon entfernt, perfekt zu sein, aber sie zeigt, dass das Erstellen generativer Kunst nicht viel Code erfordert. Ich werde mein Bestes geben, um die Schlüsselstücke zu erklären.

Die Hauptfunktion beginnt mit dem Anfangsbild zu schaffen und um die Größe des Sprites bestimmt wird . Die beiden for- Schleifen sind für die Definition eines Rahmens für jedes Sprite verantwortlich und teilen die Abmessungen des Bildes im Wesentlichen durch die Anzahl der angeforderten Sprites. Diese Werte werden verwendet, um die Koordinaten für jeden zu bestimmen.

Lassen Sie uns die Polsterung ignorieren und das Bild unten betrachten. Stellen Sie sich vor, dass jedes der vier Quadrate ein Sprite mit einer Größe von 1 darstellt. Der Rand, der an die nächste Funktion übergeben wird, bezieht sich auf die Koordinaten oben links und unten rechts. Das Tupel für das Sprite oben links wäre also (0,0,1,1), während das Tupel für das Sprite oben rechts (1,0,2,1) wäre. Diese werden als Abmessungen und Basiskoordinaten für die Quadrate jedes Sprites verwendet.

Die Funktion create_invader bestimmt den Rand für jedes Quadrat innerhalb des Sprites. Der gleiche Prozess zum Bestimmen des Rahmens wird hier angewendet und unten dargestellt, nur dass wir anstelle des vollständigen Bildes einen vordefinierten Rand verwenden, um darin zu arbeiten. Diese endgültigen Koordinaten für jedes Quadrat werden in der nächsten Funktion verwendet, um das Sprite tatsächlich zu zeichnen.

To determine the color, a simple array of three random RGB tuples and three blacks are used to simulate a 50% chance of being drawn. The lambda functions near the top of the code are responsible for generating the RGB values.

The real trick of this function is creating symmetry. Each square is paired with an element value. In the image below you can see the element values increment as they reach the center and then decrement. Squares with matching element values are drawn with the same color.

As create_square receives its parameters from create_invader, it uses a queue and the element values from before to ensure symmetry. The first occurrence of the values have their colors pushed onto the queue and the mirrored squares pop the colors off.

I realize how difficult it is to read through and understand someone else’s solution for a problem, and the roughness of the code certainly does not help with its complexity, but hopefully you’ve got a pretty good idea for how it works. Ultimately it would be incredible if you are able to scrap my code altogether and figure out an entirely different solution.

Conclusion

Generative art takes time to fully appreciate, but it’s worth it. I love being able to combine programming with a more traditional visual, and I have definitely learned a lot in every one of my projects.

Overall there may be more useful projects to pursue and generative art may not be something you need experience with, but it’s a ton of fun and you never know how it might separate you from the crowd.

Thank you for reading!