artgen

package module
v0.0.0-...-34c6d85 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 27, 2021 License: MIT Imports: 10 Imported by: 0

README

artgen

about

artgen makes ephemeral art for your enjoyment (or not). it makes it easy to generate some random art and then display it to an enduser. It could also be used to make larger art than it does by default (720p) at the cost of more time/resources.

work is underway to find a good balance of randomization (measured by beauty and variety of images produced) and speed. current default generation speed on a 1.10GHz 4-core laptop is ~370ms. read the suggestion in the usage section below to see how to use a pool of *artgen.Painting and a worker (or a few) to reduce load times.

Benchmarks

The average size of files generated with the default PNG settings is 121KB, the average size with the default JPG settings is 41KB. The other sizes have not been benchmarked for average file size but the tests are written for the other two defaults and could be modified.

goos: linux
goarch: amd64
pkg: github.com/sharkpick/artgen
cpu: Intel(R) Pentium(R) CPU N4200 @ 1.10GHz
BenchmarkGenerateDefault-4      	      50	 370613990 ns/op
BenchmarkGenerate1080pPNG-4     	      50	1237053033 ns/op
BenchmarkGenerate4kPNG-4        	      50	4021682155 ns/op
BenchmarkGenerateFavicon-4      	      50	   1811865 ns/op
BenchmarkGenerateAppleIcons-4   	      50	   8669384 ns/op
PASS
ok  	github.com/sharkpick/artgen	288.970s

usage

artgen is simple to use. you can use html templates to serve the image:

import "github.com/sharkpick/artgen"

func handleArtgen(w http.ResponseWriter, r *http.Request) {
    p := artgen.NewPainting() // returns a *Painting, ready to generate
    p.Generate() // generates and saves the image
    defer p.Cleanup() // destroy image after serving
    fmt.Println(p.File()) // shows location of the file
    if t, err := template.ParseFiles(templateFile); err != nil {
        // ... handle error 
    } else {
        t.Execute(w, p)
        // inside your template you can find the base64 encoded image in {{ .Image }}
    }
}

or change the workspace and write it to an existing directory of your choice

// generate 10 random images
func main() {
    myNewWorkspace := "./"
    for i := 0; i < 10; i++ {
        p := artgen.NewPainting(myNewWorkspace)
        p.Generate()
        // DO NOT Cleanup() here or your images will also be deleted.
    }
}

you can also change the size of the end product. you must set your desired result before running Generate()

func main() {
    width, height := 1920, 1080
    for i := 0; i < 10; i++ {
        p := artgen.NewPainting()
        p.SetWidth(width)
        p.SetHeight(height)
        // p.SetDimensions(width, height) // or do both
        p.Generate()
        defer p.Cleanup()
        // do work
    }
}

you can also use JPGs instead of PNGs when speed matters. default quality for artget.JPG is 75% but can be adjusted before running Generate().

func main() {
    p := artgen.NewPainting()
    p.SetFormat(artgen.JPG)
    p.SetQuality(50)
    p.Generate()
    defer p.Cleanup()
}

if you find your load times take too long, build a channel of *artgen.Painting objects ready to use. build a channel and then fill it when you start your server. use a worker to keep the channel filled (or as filled as you can) and use a timeout to keep a request from hanging forever when a server is too busy or your channel's buffer is not large enough.

done := make(chan interface{}) // close after server shutdown for graceful shutdown
buffer := make(chan *artgen.Painting, 24) // will hold 24 Generated() images for rapid use
func fillBuffer() {
    go func() {
        for {
            select {
            case <-done:
                return
            case buffer <- artgen.NewGeneratePainting():
            }
        }
        
    }()
}
func handleArtGen(w http.ResponseWriter, r *http.Request) {
    switch {
        case p, ok := <- buffer:
            if !ok {
                log.Panicln("Error: channel empty!")
            }
            p.WriteFile()
            defer p.Cleanup()
            // do work...
        case <-r.Context().Done():
            w.Write([]byte("request timed out"))
    }
}

Samples

artgen uses some randomness to make fun images like the below.

Sample 1 Sample 2 Sample 3 Sample 4

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SaveFile

func SaveFile(p Painting)

Types

type Configuration

type Configuration struct {
	Workspace  string // directory to write images to - tries /dev/shm and /tmp before defaulting to working directory
	Format     Format
	Resolution Resolution
	DPI        int  // no native support but can be used to calculate desired size of gg.Context
	Quality    int  // ignored by PNG
	Iterations int  // number of iterations (random polygon generation step)
	WriteFile  bool // used to prepare/generate without writing to disk to store in memory until needed
	// contains filtered or unexported fields
}

func NewJPGConfiguration

func NewJPGConfiguration(workspace ...string) Configuration

func NewPNGConfiguration

func NewPNGConfiguration(workspace ...string) Configuration

type Format

type Format int
const (
	PNG Format = iota
	JPG
)

type Painting

type Painting interface {
	File() string
	GetImage() image.Image
	GetQuality() int
	GetFormat() Format
}

type Resolution

type Resolution int
const (
	DEFAULT Resolution = iota // 720p
	HIGHER                    // 1080p
	HIGHEST                   // 4k
	LOWER                     // 360p
	LOWEST                    // 240p
	FAVICON                   // 32x32
	APPLE                     // 120x120

	// print-specific dimensions
	PRINT4x6
	PRINT5x7
	PRINT8x10
	PRINTWALLET
	POSTER11x14
	POSTER12x18
	POSTER16x20
	POSTER20x30
	POSTER24x36
	BANNER2x6
	BANNER2x8
	PHOTOGIFT
	CARD4x8
	CARD5x7
	CARDFOLDED5x7
	POSTCARD425x6
	POSTCARD5x7
	PHOTOBOOK
	BRAGBOOK
	NOTEBOOK
	NOTEPAD
	STICKERS
	CANVAS8x10
	CANVAS11x14
	CANVAS12x12
	CANVAS16x20
	CANVAS20x24
	CANVAS20x30
)

type WebImage

type WebImage struct {
	Configuration
	// contains filtered or unexported fields
}

func NewRandomJPG

func NewRandomJPG(workspace ...string) *WebImage

func NewRandomPNG

func NewRandomPNG(workspace ...string) *WebImage

func (*WebImage) Cleanup

func (w *WebImage) Cleanup()

func (WebImage) File

func (w WebImage) File() string

func (*WebImage) Generate

func (w *WebImage) Generate() *gg.Context

func (WebImage) GetFormat

func (w WebImage) GetFormat() Format

func (WebImage) GetImage

func (w WebImage) GetImage() image.Image

func (WebImage) GetQuality

func (w WebImage) GetQuality() int

func (*WebImage) Image

func (w *WebImage) Image() string

func (WebImage) PixelDimensions

func (w WebImage) PixelDimensions() (width, height int)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL