de Eric Davidson

Cum să creați artă generativă în mai puțin de 100 de linii de cod

Arta generativă, ca orice subiect de programare, poate fi intimidantă dacă nu ați încercat-o niciodată. M-am interesat mereu pentru că îmi place să găsesc noi modalități prin care programarea poate fi utilizată creativ. În plus, cred că oricine poate aprecia conceptul de artă care se creează la propriu.

Cum sa creati arta generativa in mai putin de 100
Etichetat pentru reutilizare din Pexels

Ce este arta generativă?

Arta generativă este rezultatul unui sistem care ia propriile decizii cu privire la piesă, mai degrabă decât un om. Sistemul ar putea fi la fel de simplu ca un singur program Python, atâta timp cât are reguli și un aspect al aleatoriu.

Cu programarea, este destul de simplu să veniți cu reguli și constrângeri. Asta este tot afirmația condițională. Acestea fiind spuse, găsirea unor modalități prin care aceste reguli pot crea ceva interesant poate fi dificilă.

Cum sa creati arta generativa in mai putin de 100
Conway’s Game of Life (etichetat pentru reutilizare)

Jocul vieții este un faimos set de patru reguli simple care determină „nașterea” și „moartea” fiecărei celule din sistem. Fiecare dintre reguli joacă un rol în avansarea sistemului prin fiecare generație. Deși regulile sunt simple și ușor de înțeles, modele complexe încep să apară rapid și în cele din urmă formează rezultate fascinante.

Regulile pot fi responsabile pentru crearea bazei a ceva interesant, dar chiar și ceva la fel de interesant precum Jocul vieții lui Conway este previzibil. Deoarece cele patru reguli sunt factorii determinanți pentru fiecare generație, modalitatea de a produce rezultate imprevizibile este de a introduce randomizarea la starea inițială a celulelor. Începând cu o matrice aleatorie, fiecare execuție va fi unică, fără a fi nevoie să modificați regulile.

Cele mai bune exemple de artă generativă sunt cele care găsesc o combinație de predictibilitate și aleatoriu pentru a crea ceva interesant, care este, de asemenea, statistic. irproductibil.

De ce ar trebui să o încercați?

Nu toate proiectele secundare sunt create egale, iar arta generativă poate să nu fie ceva în care sunteți înclinați să petreceți timpul. Cu toate acestea, dacă decideți să lucrați la un proiect, atunci vă puteți aștepta la aceste beneficii:

  • Experienţă – Arta generativă este doar o altă oportunitate de a perfecționa niște abilități noi și vechi. Poate servi ca o poartă către practicarea conceptelor precum algoritmi, structuri de date și chiar limbaje noi.
  • Rezultate tangibile – În lumea programării rareori ajungem să vedem ceva fizic ieșind din eforturile noastre, sau cel puțin eu nu. În acest moment am câteva afișe în sufrageria mea care afișează amprente ale artei mele generative și îmi place că programarea este responsabilă pentru asta.
  • Proiecte atractive – Cu toții am avut experiența de a explica cuiva un proiect personal, chiar și în timpul unui interviu, fără o modalitate ușoară de a transmite efortul și rezultatele proiectului. Arta generativă vorbește de la sine și majoritatea oricui va fi impresionat de creațiile tale, chiar dacă nu pot înțelege pe deplin metodele.

De unde ar trebui să începi?

Noțiuni de bază cu arta generativă este același proces ca orice proiect, cel mai crucial pas este să-ți vină o idee sau să găsești una pe care să te bazezi. Odată ce ai un obiectiv în minte, atunci poți începe să lucrezi la tehnologia necesară pentru a-l atinge.

Majoritatea proiectelor mele de artă generativă au fost realizate în Python. Este un limbaj destul de ușor de obișnuit și are câteva pachete incredibile disponibile pentru a ajuta la manipularea imaginilor, cum ar fi Pernă.

Din fericire pentru dvs., nu este nevoie să căutați foarte departe un punct de plecare, deoarece v-am furnizat mai jos un cod pentru a vă juca.

Generator Sprite

Acest proiect a început când am văzut o postare care arăta un generator de sprite scris în Javascript. Programul a creat sprite de artă de 5×5 pixeli cu câteva opțiuni de culoare aleatorii și ieșirea sa seamănă cu invadatorii de spațiu multicolori.

Știam că vreau să practic manipularea imaginii în Python, așa că m-am gândit că aș putea încerca să recreez singur acest concept. În plus, m-am gândit că aș putea să-l extind, deoarece proiectul original a fost atât de limitat în dimensiunea spritelor. Am vrut să pot specifica nu numai dimensiunea, ci și numărul acestora și chiar dimensiunea imaginii.

Iată o privire asupra a două rezultate diferite din soluția cu care am ajuns:

1611963969 550 Cum sa creati arta generativa in mai putin de 100
7×7–30–1900
1611963969 560 Cum sa creati arta generativa in mai putin de 100
43×43–6–1900

Aceste două imagini nu seamănă deloc, dar ambele sunt rezultatele aceluiași sistem. Ca să nu mai vorbim, datorită complexității imaginii și a imaginii aleatoriu din generația sprite, există o probabilitate extrem de mare ca, chiar și cu aceleași argumente, aceste imagini să fie pentru totdeauna unice. Îmi place.

Mediul

Dacă doriți să începeți să jucați cu generatorul de sprite, trebuie să faceți mai întâi o mică lucrare de bază.

Configurarea unui mediu adecvat cu Python poate fi dificilă. Dacă nu ați mai lucrat cu Python înainte, probabil că va trebui descărcați Python 2.7.10. Am avut inițial probleme la configurarea mediului, așa că, dacă începeți să întâmpinați probleme, puteți face ceea ce am făcut și să vă uitați medii virtuale. Nu în ultimul rând, asigurați-vă că aveți Pernă instalat, de asemenea.

Odată ce ați configurat mediul, puteți copia codul meu într-un fișier cu extensia .py și executați cu următoarea comandă:

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

De exemplu, comanda pentru a crea prima matrice de sprite de sus ar fi:

python spritething.py 7 30 1900

Codul

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

Această soluție este departe de a fi perfectă, dar arată că crearea de artă generativă nu necesită o tonă de cod. Voi încerca tot posibilul pentru a explica piesele cheie.

principal funcția începe prin crearea imaginii inițiale și determinarea dimensiunii spritelor. Cei doi pentru buclele sunt responsabile pentru definirea unui chenar pentru fiecare sprite, practic împărțind dimensiunile imaginii la numărul de sprite solicitate. Aceste valori sunt utilizate pentru a determina coordonatele pentru fiecare.

Să ignorăm căptușeala și să aruncăm o privire la imaginea de mai jos. Imaginați-vă că fiecare dintre cele patru pătrate reprezintă un sprite cu dimensiunea 1. Bordura care este trecută la următoarea funcție se referă la coordonatele din stânga sus și din dreapta jos. Deci tuplul pentru spriteul din stânga sus ar fi (0,0,1,1) în timp ce tuplul pentru dreapta sus ar fi (1,0,2,1). Acestea vor fi utilizate ca dimensiuni și coordonate de bază pentru pătratele fiecărui sprite.

Cum sa creati arta generativa in mai putin de 100
Exemplu de determinare a frontierelor sprite

Functia create_invader determină marginea pentru fiecare pătrat din sprite. Același proces pentru determinarea chenarului este aplicat aici și reprezentat mai jos, doar în locul imaginii complete folosim un chenar predeterminat pentru a lucra în interior. Aceste coordonate finale pentru fiecare pătrat vor fi utilizate în următoarea funcție pentru a desena efectiv sprite-ul.

1611963969 923 Cum sa creati arta generativa in mai putin de 100
Exemplu de descompunere a unui sprite de 3×3

Pentru a determina culoarea, o matrice simplă de trei tupluri RGB aleatorii și trei negri sunt folosite pentru a simula o șansă de 50% de a fi desenate. Funcțiile lambda din partea de sus a codului sunt responsabile pentru generarea valorilor RGB.

Adevăratul truc al acestei funcții este crearea simetriei. Fiecare pătrat este asociat cu o valoare de element. În imaginea de mai jos puteți vedea creșterea valorilor elementelor pe măsură ce ajung în centru și apoi decrementează. Pătratele cu valori ale elementelor potrivite sunt desenate cu aceeași culoare.

1611963970 485 Cum sa creati arta generativa in mai putin de 100
Valorile elementelor și culorile simetrice pentru un rând într-un sprite de 7×7

La fel de create_square primește parametrii săi de la create_invader, folosește o coadă și valorile elementelor dinainte pentru a asigura simetria. Prima apariție a valorilor are culorile împinse pe coadă și pătratele în oglindă deschid culorile.

1611963970 326 Cum sa creati arta generativa in mai putin de 100
Procesul complet de generare

Îmi dau seama cât de dificil este să citesc și să înțeleg soluția altcuiva pentru o problemă, iar rugozitatea codului cu siguranță nu ajută la complexitatea acesteia, dar sperăm că ai o idee destul de bună despre cum funcționează. În cele din urmă, ar fi incredibil dacă reușiți să descărcați complet codul meu și să găsiți o soluție complet diferită.

Concluzie

Arta generativă necesită timp pentru a aprecia pe deplin, dar merită. Îmi place să pot combina programarea cu un vizual mai tradițional și cu siguranță am învățat multe în fiecare dintre proiectele mele.

În general, pot exista proiecte mai utile de urmărit, iar arta generativă poate să nu fie ceva cu care aveți nevoie de experiență, dar este o mulțime de distracție și nu știți niciodată cum ar putea să vă separe de mulțime.

Mulțumesc că ai citit!