leech/thumbnail/thumbnail.go
2024-06-10 21:36:26 +02:00

80 lines
1.9 KiB
Go

package thumbnail
import (
"bytes"
"image"
"image/color"
"image/png"
"os"
"path/filepath"
"slices"
"sync"
"github.com/disintegration/imaging"
"github.com/gofiber/fiber/v2"
)
var SupportedFileTypes = []string{".png", ".PNG", ".jpg", ".JPG", ".jpeg", ".JPEG"}
var FileTypesMap = map[string]imaging.Format{
".png": imaging.PNG,
".PNG": imaging.PNG,
".jpg": imaging.JPEG,
".JPG": imaging.JPEG,
".jpeg": imaging.JPEG,
".JPEG": imaging.JPEG,
}
var thumbnailSize = 24
var thumbnailCache = map[string][]byte{}
var thumbnailCacheMutex = &sync.RWMutex{}
func IsSupportedFileType(completePath string) bool {
fileExt := filepath.Ext(completePath)
return slices.Contains(SupportedFileTypes, fileExt)
}
func GetThumbnail(c *fiber.Ctx, completePath string) {
c.Set(fiber.HeaderContentType, "image")
thumbnailCacheMutex.RLock()
bytesThumb, ok := thumbnailCache[completePath]
thumbnailCacheMutex.RUnlock()
if ok {
c.Write(bytesThumb)
return
}
fileExt := filepath.Ext(completePath)
if !slices.Contains(SupportedFileTypes, fileExt) {
return
}
f, err := os.Open(completePath)
if err != nil {
return
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return
}
// load images and make 64x64 thumbnails of them
thumbnail := imaging.Thumbnail(img, thumbnailSize, thumbnailSize, imaging.CatmullRom)
// create a new blank image
dst := imaging.New(thumbnailSize, thumbnailSize, color.NRGBA{0, 0, 0, 0})
// paste thumbnails into the new image side by side
dst = imaging.Paste(dst, thumbnail, image.Pt(0, 0))
// save the combined image to buffer
var buf bytes.Buffer
if FileTypesMap[fileExt] == imaging.PNG {
err = png.Encode(&buf, dst)
} else {
err = imaging.Encode(&buf, dst, FileTypesMap[fileExt])
}
if err != nil {
return
}
thumbnailCacheMutex.Lock()
thumbnailCache[completePath] = buf.Bytes()
thumbnailCacheMutex.Unlock()
c.Write(buf.Bytes())
}