Arte generativa com fórmula simples em Go
Gerando imagens legais, ou arte generativa com uma fórmula simples em Go (Golang)
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) :)