2024-10-26 23:47:48 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-10-29 15:18:21 +00:00
|
|
|
"fmt"
|
2024-10-26 23:47:48 +00:00
|
|
|
"image"
|
|
|
|
"log"
|
|
|
|
"os"
|
2024-10-28 23:29:20 +00:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2024-10-26 23:47:48 +00:00
|
|
|
|
2024-10-27 17:15:14 +00:00
|
|
|
"github.com/disintegration/gift"
|
|
|
|
|
2024-10-26 23:47:48 +00:00
|
|
|
_ "image/jpeg"
|
|
|
|
"image/png"
|
2024-10-28 23:29:20 +00:00
|
|
|
|
|
|
|
_ "golang.org/x/image/webp"
|
2024-10-26 23:47:48 +00:00
|
|
|
)
|
|
|
|
|
2024-10-27 16:21:28 +00:00
|
|
|
type ImageFilters struct {
|
2024-10-31 11:54:39 +00:00
|
|
|
Colorize [3]float64
|
|
|
|
Contrast float32
|
|
|
|
Gamma float32
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeDefaultImageFilters() ImageFilters {
|
|
|
|
return ImageFilters{
|
|
|
|
Colorize: [3]float64{247, 40, 60},
|
|
|
|
Contrast: -35,
|
|
|
|
Gamma: 0.8,
|
|
|
|
}
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
|
|
|
|
2024-10-28 23:29:20 +00:00
|
|
|
func pickRandomImage(dir string) (string, error) {
|
2024-10-30 18:22:03 +00:00
|
|
|
|
|
|
|
dir = config.ImagesDir + dir
|
|
|
|
fmt.Printf("getting random file from %v\n", dir)
|
2024-10-28 23:29:20 +00:00
|
|
|
randomImg, filename, _ := getRandomFile(dir)
|
|
|
|
filenameNoExt := strings.TrimSuffix(filename, filepath.Ext(filename))
|
|
|
|
|
|
|
|
//check to see if rendered copy already exists
|
|
|
|
fileExists, err := fileExistsInCache(filenameNoExt)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2024-10-30 18:22:03 +00:00
|
|
|
curr := config.Cache + filenameNoExt
|
2024-10-28 23:29:20 +00:00
|
|
|
if !fileExists {
|
|
|
|
img, err := loadImage(randomImg)
|
|
|
|
if err != nil {
|
2024-10-30 18:22:03 +00:00
|
|
|
fmt.Printf("failed to load image %v", randomImg)
|
2024-10-28 23:29:20 +00:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
dst := processImage(img, config)
|
|
|
|
saveImage(curr, dst)
|
|
|
|
} else {
|
|
|
|
log.Println("file already exists in cache. skipping image processing")
|
|
|
|
}
|
|
|
|
return curr, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadImage(filename string) (image.Image, error) {
|
2024-10-26 23:47:48 +00:00
|
|
|
f, err := os.Open(filename)
|
|
|
|
if err != nil {
|
2024-10-29 15:18:21 +00:00
|
|
|
|
2024-10-28 23:29:20 +00:00
|
|
|
return nil, err
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
img, _, err := image.Decode(f)
|
|
|
|
if err != nil {
|
2024-10-28 23:29:20 +00:00
|
|
|
return nil, err
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
2024-10-28 23:29:20 +00:00
|
|
|
return img, nil
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
|
|
|
|
2024-10-28 23:29:20 +00:00
|
|
|
func saveImage(filename string, img image.Image) error {
|
2024-10-26 23:47:48 +00:00
|
|
|
f, err := os.Create(filename)
|
|
|
|
if err != nil {
|
2024-10-28 23:29:20 +00:00
|
|
|
return err
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
err = png.Encode(f, img)
|
|
|
|
if err != nil {
|
2024-10-28 23:29:20 +00:00
|
|
|
return err
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
2024-10-28 23:29:20 +00:00
|
|
|
return nil
|
2024-10-26 23:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func processImage(img image.Image, config Config) image.Image {
|
2024-10-31 11:54:39 +00:00
|
|
|
h32 := float32(config.ImageFilters.Colorize[0])
|
|
|
|
s32 := float32(config.ImageFilters.Colorize[1])
|
|
|
|
l32 := float32(config.ImageFilters.Colorize[2])
|
2024-10-26 23:47:48 +00:00
|
|
|
|
|
|
|
g := gift.New(
|
2024-10-31 11:54:39 +00:00
|
|
|
gift.Colorize(h32, s32, l32),
|
|
|
|
gift.Contrast(config.ImageFilters.Contrast),
|
|
|
|
gift.Gamma(config.ImageFilters.Gamma),
|
2024-10-26 23:47:48 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
dst := image.NewRGBA(g.Bounds(img.Bounds()))
|
|
|
|
g.Draw(dst, img)
|
|
|
|
|
|
|
|
return dst
|
|
|
|
}
|