catbase/plugins/cowboy/cowboy_image.go

112 lines
2.5 KiB
Go
Raw Normal View History

2022-07-21 15:25:10 +00:00
package cowboy
import (
"bytes"
"fmt"
"image"
"image/draw"
"image/png"
"math"
2022-07-21 15:25:10 +00:00
"os"
"path"
2022-07-22 21:06:55 +00:00
"sync"
2022-07-21 15:25:10 +00:00
"github.com/nfnt/resize"
2022-07-22 21:06:55 +00:00
"github.com/rs/zerolog/log"
2022-07-21 15:25:10 +00:00
"github.com/velour/catbase/config"
"github.com/velour/catbase/plugins/emojy"
)
2022-07-22 21:06:55 +00:00
var (
2022-07-22 22:27:20 +00:00
cowboyCache = map[string]image.Image{}
2022-07-22 21:06:55 +00:00
cowboyMutex = sync.Mutex{}
)
func getEmojy(emojyPath, baseEmojyURL, name string) (image.Image, error) {
files, _, err := emojy.AllFiles(emojyPath, baseEmojyURL)
2022-07-21 15:25:10 +00:00
if err != nil {
return nil, err
}
fname, ok := files[name]
if !ok {
return nil, fmt.Errorf("could not find emojy: %s", name)
}
f, err := os.Open(fname)
if err != nil {
return nil, err
}
img, _, err := image.Decode(f)
if err != nil {
return nil, err
}
return img, nil
}
func getCowboyHat(c *config.Config, emojyPath string) (image.Image, error) {
2022-07-21 15:25:10 +00:00
p := path.Join(emojyPath, c.Get("cowboy.hatname", "hat.png"))
2022-07-21 15:39:50 +00:00
p = path.Clean(p)
2022-07-21 15:25:10 +00:00
f, err := os.Open(p)
if err != nil {
return nil, err
}
img, _, err := image.Decode(f)
if err != nil {
return nil, err
}
return img, nil
}
func cowboyifyImage(c *config.Config, emojyPath string, input image.Image) (image.Image, error) {
hat, err := getCowboyHat(c, emojyPath)
2022-07-21 15:25:10 +00:00
if err != nil {
return nil, err
}
inputW, inputH := float64(input.Bounds().Max.X), float64(input.Bounds().Max.Y)
2022-07-21 15:25:10 +00:00
hatW, hatH := float64(hat.Bounds().Max.X), float64(hat.Bounds().Max.Y)
targetSZ := math.Max(inputW, inputH)
dst := image.NewRGBA(image.Rect(0, 0, int(targetSZ), int(targetSZ)))
newH := uint(targetSZ / hatW * hatH)
hat = resize.Resize(uint(targetSZ), newH, hat, resize.Lanczos3)
2022-07-21 15:25:10 +00:00
draw.Draw(dst, input.Bounds(), input, image.Point{}, draw.Src)
draw.Draw(dst, hat.Bounds(), hat, image.Point{}, draw.Over)
return dst, nil
}
2022-07-22 22:27:20 +00:00
func cowboy(c *config.Config, emojyPath, baseEmojyURL, name string) (image.Image, error) {
2022-07-22 21:06:55 +00:00
cowboyMutex.Lock()
defer cowboyMutex.Unlock()
if img, ok := cowboyCache[name]; ok {
log.Debug().Msgf(":cowboy_using_cached_image: %s", name)
return img, nil
}
log.Debug().Msgf(":cowboy_generating_image: %s", name)
emjy, err := getEmojy(emojyPath, baseEmojyURL, name)
2022-07-21 15:25:10 +00:00
if err != nil {
return nil, err
}
2022-07-22 21:06:55 +00:00
img, err := cowboyifyImage(c, emojyPath, emjy)
2022-07-22 22:27:20 +00:00
if err != nil {
return nil, err
}
cowboyCache[name] = img
return img, nil
}
func encode(img image.Image, err error) ([]byte, error) {
2022-07-21 15:25:10 +00:00
if err != nil {
return nil, err
}
w := bytes.NewBuffer([]byte{})
err = png.Encode(w, img)
if err != nil {
return nil, err
}
return w.Bytes(), nil
}
2022-07-22 21:06:55 +00:00
func cowboyClearCache() {
cowboyMutex.Lock()
defer cowboyMutex.Unlock()
2022-07-22 22:27:20 +00:00
cowboyCache = map[string]image.Image{}
2022-07-22 21:06:55 +00:00
}