Arte generativa com fórmula simples em Go
Tags: generativeart, go, braziliandevs, programming
Published: 2024-01-09 01:26:02

---
title: Arte generativa com fórmula simples em Go
published: true
description: Gerando imagens legais, ou arte generativa com uma fórmula simples em Go (Golang)

tags: generativeart,go,braziliandevs,programming
# cover_image: ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wytutomidyjzcripmc3m.jpg)
# Use a ratio of 100:42 for best results.
# published_at: 2024-01-09 01:19 +0000
---

![Imagem pichada em Campinas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wytutomidyjzcripmc3m.jpg)

### Inspiração

Essa imagem, que me persegue por várias ruas do Centro de Campinas, me faz pensar em alguma forma de desenhar através de um programa.Em outros momentos já vinha testando alguma coisa:

> https://paulohrpinheiro.xyz/texts/go/2019-02-18-gerando-imagens-em-go-com-biblioteca-padrao.html

> https://github.com/paulohrpinheiro/generative-art

Explorando essa fórmula, da maneira que costumo, cheguei a uma redução bem interessante:

    C + C * X * Y

Em que `C` é uma constante qualquer, e o par `X`, `Y`, coordenadas da imagem gerada em um tamanho predeterminado (em geral 1000 pontos) a partir da origem `(0,0)`. Mas o interessante é colorir essas imagens, para isso é usado resultado dessa conta módulo `M`, em que M é o máximo de cores que se deseja usar.

### O programa

> PS: usei range no loop for, coisa que só está disponível na versão 1.22rc1, futuramente 1.22!

```
    package main

    import (
    	"flag"
    	"image"
    	"image/color/palette"
    	"image/png"
    	"os"
    )

    const (
    	defaultImageSize = 1000
    	defaultMaxColors = 150
    	defaultConstant  = 10
    	defaultFileName  = "formula.png"
    )

    func main() {
    	fileName := flag.String("filename", defaultFileName, "filename to save image (.png)")
    	imageSize := flag.Int("size", defaultImageSize, "size of image")
    	constant := flag.Int("constant", defaultConstant, "constant for formula (c): c-c*x*y")
    	maxColors := flag.Int("colors", len(palette.WebSafe), "number of colors")

    	flag.Parse()

    	rect := image.Rect(0, 0, *imageSize, *imageSize)
    	img := image.NewPaletted(rect, palette.WebSafe)

    	for x := range *imageSize {
    		for y := range *imageSize {
    			value := (*constant - *constant*x*y)
    			color := uint8(value % *maxColors)

    			img.SetColorIndex(x, y, color)
    		}
    	}

    	f, err := os.Create(*fileName)
    	if err != nil {
    		panic(err)
    	}

    	defer f.Close()
    	png.Encode(f, img)
}
``` 

Duas coisas que aprendi nessa empreitada, foram o pacote `flag` e o `image/color/palette`.

Ao invés de construir minha própria paleta de cores como vinha fazendo há algum tempo, agora uso a paleta `palette.WebSafe`. Outra opção pronta é a `palette.Plan9`:

> https://pkg.go.dev/image/color/palette

O pacote flag permite uma maneira rápida (e não sofisticada) de capturar argumentos em linha de comando, como por exemplo:

    go run formula.go -filename formula-colors:50-constant:10-size:10.png -colors 50

Em caso de parâmetro errado:

    $ go run formula.go -nada-a-ver
    flag provided but not defined: -nada-a-ver
    Usage of /tmp/go-build942068976/b001/exe/formula:
      -colors int
        	number of colors (default 216)
      -constant int
        	constant for formula (c): c-c*x*y (default 10)
      -filename string
        	filename to save image (.png) (default "formula.png")
      -size int
        	size of image (default 1000)
    exit status 2

### Algumas imagens

Mudando os parâmetros tem-se resultados interessantemente diferentes (ou não) :)

#### colors:100 constant:10

![colors:100 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:100-constant:10-size:10.png)

#### colors:216 constant:10

![colors:216 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:216-constant:10-size:10.png)

#### colors:80 constant:10

![colors:80 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:80-constant:10-size:10.png)

#### colors:60 constant:10

![colors:60 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:60-constant:10-size:10.png)

#### colors:90 constant:10

![colors:90 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:90-constant:10-size:10.png)

#### colors:200 constant:10

![colors:200 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:200-constant:10-size:10.png)

#### colors:70 constant:10

![colors:70 constant:10](https://paulohrpinheiro.xyz/texts/go/images/formula-colors:70-constant:10-size:10.png)