DEV Community

Paulo H. R. Pinheiro
Paulo H. R. Pinheiro

Posted on • Edited on

Arte generativa com fórmula simples em Go

Imagem pichada em Campinas

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
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode




Algumas imagens

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

colors:100 constant:10

colors:100 constant:10

colors:216 constant:10

colors:216 constant:10

colors:80 constant:10

colors:80 constant:10

colors:60 constant:10

colors:60 constant:10

colors:90 constant:10

colors:90 constant:10

colors:200 constant:10

colors:200 constant:10

colors:70 constant:10

colors:70 constant:10

Top comments (0)