You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
memos/common/image.go

77 lines
1.5 KiB
Go

package common
import (
"bytes"
"fmt"
"image"
"image/jpeg"
"image/png"
"os"
"path/filepath"
"strings"
"github.com/disintegration/imaging"
)
const (
ThumbnailDir = ".thumbnail_cache"
ThumbnailSize = 302 // Thumbnail size should be defined by frontend
)
func ResizeImageFile(dst, src string, mime string) error {
srcBytes, err := os.ReadFile(src)
if err != nil {
return fmt.Errorf("Failed to open %s: %s", src, err)
}
dstBytes, err := ResizeImageBlob(srcBytes, ThumbnailSize, mime)
if err != nil {
return fmt.Errorf("Failed to resise %s: %s", src, err)
}
err = os.MkdirAll(filepath.Dir(dst), os.ModePerm)
if err != nil {
return fmt.Errorf("Failed to mkdir for %s: %s", dst, err)
}
err = os.WriteFile(dst, dstBytes, 0666)
if err != nil {
return fmt.Errorf("Failed to write %s: %s", dst, err)
}
return nil
}
func ResizeImageBlob(data []byte, maxSize int, mime string) ([]byte, error) {
var err error
var oldImage image.Image
switch strings.ToLower(mime) {
case "image/jpeg":
oldImage, err = jpeg.Decode(bytes.NewReader(data))
case "image/png":
oldImage, err = png.Decode(bytes.NewReader(data))
default:
return nil, fmt.Errorf("mime %s is not support", mime)
}
if err != nil {
return nil, err
}
newImage := imaging.Resize(oldImage, maxSize, 0, imaging.NearestNeighbor)
var newBuffer bytes.Buffer
switch mime {
case "image/jpeg":
err = jpeg.Encode(&newBuffer, newImage, nil)
case "image/png":
err = png.Encode(&newBuffer, newImage)
}
if err != nil {
return nil, err
}
return newBuffer.Bytes(), nil
}