linstrom/storage/mediaProvider/preprocessor.go
mStar ee172d84a8 work on preprocessor for storing
also add aws dependency if someone wants to use it
2024-09-25 17:08:43 +02:00

85 lines
2 KiB
Go

package mediaprovider
import (
"bytes"
"encoding/base64"
"errors"
"image"
"image/jpeg"
"image/png"
"io"
"strings"
"github.com/gabriel-vasile/mimetype"
"github.com/gen2brain/avif"
"golang.org/x/image/draw"
"golang.org/x/image/webp"
)
var ErrUnknownImageType = errors.New("unknown image format")
func Compress(dataReader io.Reader, mimeType *string) (io.Reader, error) {
data, err := io.ReadAll(dataReader)
if err != nil {
return nil, err
}
if mimeType == nil {
*mimeType = mimetype.Detect(data).String()
}
uberType, subType, _ := strings.Cut(*mimeType, "/")
var dataOut []byte
switch uberType {
case "text":
case "application":
case "image":
dataOut, err = compressImage(data, subType, 1280, 720)
case "video":
dataOut, err = compressVideo(data, subType)
case "audio":
case "font":
default:
}
if err != nil && err != ErrUnknownImageType {
return nil, err
}
dataOut = compressBase64(dataOut)
return bytes.NewReader(dataOut), nil
}
func compressVideo(dataIn []byte, subType string) (dataOut []byte, err error) {
// TODO: Implement me
panic("Implement me")
}
func compressImage(dataIn []byte, subType string, maxSizeX, maxSizeY uint) (dataOut []byte, err error) {
imageSize := image.Rect(0, 0, int(maxSizeX), int(maxSizeY))
dst := image.NewRGBA(imageSize)
var sourceImage image.Image
switch subType {
case "png":
sourceImage, err = png.Decode(bytes.NewReader(dataIn))
if err != nil {
return nil, err
}
case "jpg", "jpeg":
sourceImage, err = jpeg.Decode(bytes.NewReader(dataIn))
case "webp":
sourceImage, err = webp.Decode(bytes.NewReader(dataIn))
case "avif":
sourceImage, err = avif.Decode(bytes.NewReader(dataIn))
default:
return nil, ErrUnknownImageType
}
if err != nil {
return nil, err
}
draw.CatmullRom.Scale(dst, imageSize, sourceImage, sourceImage.Bounds(), draw.Src, nil)
return dst.Pix, nil
}
func compressBase64(dataIn []byte) []byte {
result := []byte{}
base64.StdEncoding.Encode(result, dataIn)
return result
}