
A arte generativa (arte generativa ou processual) pode assustá-lo se você nunca a encontrou antes. Em suma, este é um conceito de arte que literalmente se cria e não requer conhecimento de programação grave pela primeira vez. Então eu decidi diluir um pouco nossa fita, eles dirigiram.
O que é arte generativa?
Este é o resultado de um sistema que toma suas próprias decisões sobre um objeto em vez de uma pessoa. Um sistema pode ser tão simples quanto um único programa Python se tiver regras e um momento de chance.
Com a programação, é muito fácil criar regras e restrições. Existem instruções condicionais para isso. Mas encontrar maneiras de fazer essas regras criarem algo interessante pode não ser tão simples.
Jogo da vida de ConwayO Jogo da Vida de Conway é um conjunto bem conhecido de quatro regras simples que definem o "nascimento" e a "morte" de cada célula do sistema. Cada regra desempenha um papel na promoção do sistema através de cada geração. Embora as regras sejam simples e fáceis de entender, emergem rapidamente padrões complexos que acabam por produzir resultados emocionantes.
As regras podem ser responsáveis por estabelecer as bases para algo interessante, mas até algo tão emocionante quanto o Jogo da Vida de Conway é previsível. As quatro regras são os fatores determinantes para cada geração. Portanto, para obter resultados inesperados, é necessário introduzir a randomização no estado inicial das células. Começando com uma matriz aleatória, cada execução será única sem a necessidade de alterar as regras.
Os melhores exemplos de arte generativa são aqueles que encontram uma combinação de previsibilidade e aleatoriedade para criar algo interessante que é estatisticamente impossível de repetir.
Por que você deveria tentar isso?
Arte generativa nem sempre será o que você deseja gastar. Mas se você decidir trabalhar nisso, poderá contar com as seguintes vantagens:
- Experiência. A arte generativa é outra oportunidade de aprimorar novas e antigas habilidades. Pode servir como uma entrada para elaborar conceitos como algoritmos, estruturas de dados e até novas linguagens.
- Resultados tangíveis. Na programação, raramente vemos os resultados físicos de nossos esforços. Bem, ou pelo menos eu não vejo. Agora, na minha sala, há vários pôsteres com gravuras da minha arte processual. E eu gosto que isso seja feito por código.
- Projetos atraentes. Todos tiveram a experiência de explicar um projeto pessoal a alguém, possivelmente até durante uma entrevista. A arte generativa fala por si. A maioria das pessoas apreciará os resultados, mesmo que não consigam entender completamente os métodos.
Por onde começar?
Começar com arte generativa é o mesmo processo de começar com qualquer outro projeto. O passo mais importante é ter uma ideia ou encontrá-la para um maior desenvolvimento. Depois de ter um objetivo, você pode começar a trabalhar em sua conquista.
A maioria dos meus projetos criativos está em Python. É uma linguagem bastante simples, com muitos pacotes úteis que ajudam no processamento de imagens. Por exemplo,
travesseiro .
Felizmente, você não precisa procurar muito por onde começar. Abaixo, compartilharei meu código.
Gerador de Sprite
Este projeto começou quando vi uma postagem com um gerador de sprites escrito em JavaScript. O programa criou sprites de arte 5 × 5 pixels com opções de cores aleatórias e seu resultado se assemelhava a invasores de espaço multicoloridos.
Como eu queria praticar o processamento de imagens em Python, decidi recriar esse conceito. Além disso, achei que poderia expandi-lo, pois o projeto original era muito limitado no tamanho dos sprites. E quero indicar não apenas o tamanho dos sprites, mas também o número e até o tamanho da imagem.
Aqui estão dois resultados diferentes do meu programa:
7x7-30–1900
43x43-6–1900Essas duas imagens são completamente diferentes uma da outra, mas são os dois resultados do mesmo sistema. Sem mencionar o fato de que, devido à complexidade e geração aleatória de sprites, há uma alta probabilidade de que, mesmo com os mesmos argumentos, essas imagens sejam para sempre únicas. Eu amo isso
Meio ambiente
Antes de se familiarizar com o gerador de sprites, você deve preparar uma pequena base para o trabalho.
Se você não trabalhou com Python antes, baixe o
Python 2.7.10 . No começo, tive problemas com a configuração do ambiente, se você também os encontrar, procure em
ambientes virtuais . E verifique se o
Pillow também está instalado.
Após configurar o ambiente, você pode copiar meu código em um arquivo com a extensão
.py e executar o seguinte comando:
python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]
Por exemplo, o comando para criar a primeira matriz de sprites seria:
python spritething.py 7 30 1900
Código
import PIL, random, sys from 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]))
Essa solução ainda está longe de ser perfeita, mas mostra que a criação de arte generativa não requer uma tonelada de código. Vou explicar os pontos principais.
A função principal começa com a criação da imagem original e a determinação do tamanho dos sprites. Dois
para loops são responsáveis por determinar a borda de cada sprite, basicamente dividindo o tamanho da imagem pelo número de sprites solicitados. Esses valores são usados para determinar as coordenadas de cada um deles.
Dê uma olhada na imagem abaixo. Imagine que cada um dos quatro quadrados seja um sprite com tamanho 1. A borda que é passada para a próxima função refere-se às coordenadas dos cantos superior esquerdo e inferior direito. Portanto, a tupla no sprite superior esquerdo será (0,0,1,1) e a tupla no canto superior direito será (1,0,2,1). Eles serão usados como dimensões e coordenadas de base para os quadrados de cada sprite.
Exemplo de definição de bordas de spriteA função
create_invader define a borda de cada quadrado dentro do sprite. O mesmo processo de determinação do limite é aplicado aqui e é apresentado abaixo, somente em vez da imagem completa usamos uma borda predefinida para trabalhar dentro. Essas coordenadas finais para cada quadrado serão usadas na próxima função para desenhar um sprite.
Exemplo de quebra de sprite 3 × 3Para determinar a cor, uma matriz simples de três tuplas RGB aleatórias e três pretas é usada para simular uma chance de 50% de serem desenhadas. As funções Lambda na parte superior do código são responsáveis por gerar valores RGB.
O verdadeiro truque dessa função é criar simetria. Cada quadrado está associado a um valor do elemento. A figura abaixo mostra como os valores dos elementos aumentam à medida que atingem o centro e depois diminuem. Quadrados com valores de elemento correspondentes são exibidos na mesma cor.
Valores dos elementos e cores simétricas para uma string em um sprite 7 × 7Como
create_square obtém seus parâmetros de
create_invader , ele usa os valores da fila e do elemento anterior para garantir simetria. Quando os valores aparecem pela primeira vez, suas cores são colocadas na fila e os quadrados espelhados removem as cores.
Processo completo de criaçãoEntendo como é difícil ler a solução de outra pessoa para o problema e o código torto, mas espero que você encontre esse aplicativo. Vai ser legal se você desistir completamente do meu código e encontrar uma solução completamente diferente.
Conclusão
A arte generativa leva tempo para atingir todo o seu potencial. Em geral, pode haver projetos mais úteis que a arte generativa, que nem sempre vale o tempo. Mas é muito divertido e você nunca sabe onde isso pode ser útil.