
El arte generativo (arte generativo o de procedimiento) puede asustarlo si nunca antes lo ha encontrado. En resumen, este es un concepto de arte que literalmente se crea a sí mismo y no requiere conocimientos de programación hardcore por primera vez. Así que decidí diluir un poco nuestra cinta, condujeron.
¿Qué es el arte generativo?
Este es el resultado de un sistema que toma sus propias decisiones sobre un objeto en lugar de una persona. Un sistema puede ser tan simple como un solo programa de Python si tiene reglas y un momento de oportunidad.
Con la programación, es bastante fácil crear reglas y restricciones. Hay declaraciones condicionales para esto. Pero encontrar formas de hacer que estas reglas creen algo interesante puede no ser tan simple.
El juego de la vida de ConwayEl Juego de la vida de Conway es un conocido conjunto de cuatro reglas simples que definen el "nacimiento" y la "muerte" de cada célula del sistema. Cada regla juega un papel en la promoción del sistema a través de cada generación. Aunque las reglas son simples y fáciles de entender, rápidamente surgen patrones complejos que finalmente producen resultados emocionantes.
Las reglas pueden ser responsables de sentar las bases de algo interesante, pero incluso algo tan emocionante como el Juego de la Vida de Conway es predecible. Las cuatro reglas son los factores determinantes para cada generación. Por lo tanto, para obtener resultados inesperados, debe introducir la aleatorización en el estado inicial de las celdas. Comenzando con una matriz aleatoria, cada ejecución será única sin la necesidad de cambiar las reglas.
Los mejores ejemplos de arte generativo son aquellos que encuentran una combinación de previsibilidad y aleatoriedad para crear algo interesante que es estadísticamente imposible de repetir.
¿Por qué deberías probar esto?
El arte generativo no siempre será en lo que quieras pasar el tiempo. Pero si decide trabajar en ello, puede contar con las siguientes ventajas:
- Experiencia. El arte generativo es otra oportunidad para perfeccionar habilidades nuevas y antiguas. Puede servir como entrada para elaborar conceptos como algoritmos, estructuras de datos e incluso nuevos lenguajes.
- Resultados tangibles En programación, rara vez vemos los resultados físicos de nuestros esfuerzos. Bueno, o al menos no lo veo. En este momento en mi sala de estar hay varios carteles con impresiones de mi arte procesal. Y me gusta que esto se haga por código.
- Diseños atractivos. Todos tenían la experiencia de explicar un proyecto personal a alguien, posiblemente incluso durante una entrevista. El arte generativo habla por sí mismo. La mayoría de las personas apreciarán los resultados, incluso si no pueden entender completamente los métodos.
Por donde empezar
Comenzar con el arte generativo es el mismo proceso que comenzar con cualquier otro proyecto. El paso más importante es tener una idea o encontrarla para un mayor desarrollo. Una vez que tenga un objetivo, puede comenzar a trabajar en su logro.
La mayoría de mis proyectos creativos están en Python. Es un lenguaje bastante simple con muchos paquetes útiles que ayudan con el procesamiento de imágenes. Por ejemplo,
Pillow .
Afortunadamente, no tiene que buscar mucho por dónde empezar; a continuación compartiré mi código.
Generador de sprites
Este proyecto comenzó cuando vi una publicación con un generador de sprites escrito en JavaScript. El programa creó sprites artísticos de 5 × 5 píxeles con opciones de color al azar, y su resultado se parecía a los invasores espaciales multicolores.
Quería practicar el procesamiento de imágenes en Python, así que decidí recrear este concepto yo mismo. Además, pensé que podría expandirlo, ya que el proyecto original era muy limitado en cuanto al tamaño de los sprites. Y quiero indicar no solo el tamaño de los sprites, sino también su número e incluso el tamaño de la imagen.
Aquí hay dos resultados diferentes de mi programa:
7x7-30–1900
43x43-6–1900Estas dos imágenes son completamente diferentes entre sí, pero ambas son el resultado del mismo sistema. Sin mencionar el hecho de que debido a la complejidad y la generación aleatoria de sprites, existe una alta probabilidad de que, incluso con los mismos argumentos, estas imágenes sigan siendo para siempre únicas. Me encanta
Medio ambiente
Antes de familiarizarse con el generador de sprites, debe preparar una pequeña base para el trabajo.
Si no ha trabajado con Python antes, descargue
Python 2.7.10 . Al principio, tuve problemas con la configuración del entorno, si también los encuentra, busque en
entornos virtuales . Y asegúrese de que
Pillow también esté instalado.
Después de configurar el entorno, puede copiar mi código a un archivo con la extensión
.py y ejecutar el siguiente comando:
python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]
Por ejemplo, el comando para crear la primera matriz de sprites sería:
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]))
Esta solución aún está lejos de ser perfecta, pero muestra que la creación de arte generativo no requiere una tonelada de código. Explicaré los puntos clave.
La función principal comienza con la creación de la imagen original y la determinación del tamaño de los sprites. Dos bucles
for son responsables de determinar el borde de cada sprite, básicamente dividiendo el tamaño de la imagen por el número de sprites solicitados. Estos valores se utilizan para determinar las coordenadas para cada uno de ellos.
Echa un vistazo a la imagen de abajo. Imagine que cada uno de los cuatro cuadrados es un sprite de tamaño 1. El borde que se pasa a la siguiente función se refiere a las coordenadas de las esquinas superior izquierda e inferior derecha. Entonces la tupla en el sprite superior izquierdo será (0,0,1,1), y la tupla en la parte superior derecha será (1,0,2,1). Se utilizarán como dimensiones y coordenadas de base para los cuadrados de cada sprite.
Ejemplo de definición de bordes de spritesLa función
create_invader define el borde para cada cuadrado dentro del sprite. El mismo proceso de determinar el límite se aplica aquí y se presenta a continuación, solo que en lugar de la imagen completa, usamos un borde predefinido para trabajar dentro. Estas coordenadas finales para cada cuadrado se usarán en la siguiente función para dibujar un sprite.
Ejemplo de desglose de sprites 3 × 3Para determinar el color, se utiliza una matriz simple de tres tuplas RGB aleatorias y tres negras para simular un 50% de posibilidades de ser dibujado. Las funciones de Lambda en la parte superior del código son responsables de generar valores RGB.
El verdadero truco de esta función es crear simetría. Cada cuadrado está asociado con un valor de elemento. La siguiente figura muestra cómo los valores de los elementos aumentan a medida que alcanzan el centro y luego disminuyen. Los cuadrados con valores de elementos coincidentes se muestran en el mismo color.
Valores de elementos y colores simétricos para una cadena en un sprite 7 × 7Dado que
create_square obtiene sus parámetros de
create_invader , utiliza la cola y los valores de elementos anteriores para garantizar la simetría. Cuando aparecen los valores por primera vez, sus colores se colocan en la cola y los cuadrados de espejo eliminan los colores.
Proceso de creación completaEntiendo lo difícil que es leer la solución de otra persona al problema y el código torcido, pero espero que encuentre esta aplicación. Será genial si abandonas por completo mi código y encuentras una solución completamente diferente.
Conclusión
El arte generativo toma tiempo para alcanzar su máximo potencial. En general, puede haber proyectos más útiles que el arte generativo, que no siempre vale la pena. Pero es muy divertido y nunca se sabe dónde puede ser útil.