161 lines
3.7 KiB
Go
161 lines
3.7 KiB
Go
package image
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"mime/multipart"
|
|
"os"
|
|
"strconv"
|
|
|
|
"clickandjoin.app/storageserver/modules/utils"
|
|
gocnjhelper "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper"
|
|
"github.com/h2non/bimg"
|
|
)
|
|
|
|
func FileTypeVerification(fileType string) bool {
|
|
for _, validFileType := range utils.ValidFileTypes {
|
|
if fileType == "image/"+validFileType {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func createUserFolder(userId string) error {
|
|
path := utils.GetUserStoragePath(userId)
|
|
|
|
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
|
|
err = os.Mkdir(path, os.ModePerm)
|
|
|
|
if err != nil && !errors.Is(err, os.ErrExist) {
|
|
gocnjhelper.LogErrorf("Failed to create user folder, err: %s", err)
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func SaveImage(fileHeader *multipart.FileHeader, userId string, imagePath string, imageWidth int, imageHeight int, imageQuality int) (err error) {
|
|
err = createUserFolder(userId)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
f, err := fileHeader.Open()
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to open file header, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
fileData, err := io.ReadAll(f)
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to read file, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
// prevent images that have a small resolution from being made larger by the size specified
|
|
size, err := bimg.NewImage(fileData).Size()
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to get image size, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
if size.Width < imageWidth {
|
|
imageWidth = size.Width
|
|
}
|
|
|
|
if size.Height < imageHeight {
|
|
imageHeight = size.Height
|
|
}
|
|
|
|
/*
|
|
TODO: Remove this part of the conversion once a newer version of vips (>= vips-8.7.4-Sat) is installed (if moved to new server)
|
|
All image formats that do not correspond to jpeg are converted, because with the currently installed version of vips the processing of other image formats does not work.
|
|
Installing a new version of vips is too time consuming.
|
|
This part must be removed once moved to the new server.
|
|
*/
|
|
newImage := fileData
|
|
|
|
if fileHeader.Header.Get("Content-Type") != "image/jpeg" {
|
|
newImage, err = bimg.NewImage(fileData).Convert(bimg.JPEG)
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to convert image to png, err: %s", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
newImage, err = bimg.NewImage(newImage).Process(bimg.Options{
|
|
Width: imageWidth,
|
|
Height: imageHeight,
|
|
Quality: imageQuality,
|
|
})
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to process image, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
err = bimg.Write(imagePath+".webp", newImage)
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to save image, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetImage(userId string, fileName string, imageSize string) ([]byte, error) {
|
|
imgSize, err := strconv.Atoi(imageSize)
|
|
|
|
if err != nil {
|
|
imgSize = utils.DefaultImageSize
|
|
}
|
|
|
|
buffer, err := bimg.Read(utils.GetUserStoragePath(userId) + fileName)
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to read image, err: %s", err)
|
|
return []byte{}, err
|
|
}
|
|
|
|
// check that the value has not been manipulated and is greater than the largest index value in the list
|
|
if imgSize > len(utils.ImageSizes)-1 {
|
|
imgSize = utils.DefaultImageSize
|
|
}
|
|
|
|
resolution := utils.ImageSizes[imgSize]
|
|
|
|
newImage, err := bimg.NewImage(buffer).ForceResize(resolution, resolution)
|
|
|
|
if err != nil {
|
|
gocnjhelper.LogErrorf("Failed to force resize, err: %s", err)
|
|
return []byte{}, err
|
|
}
|
|
|
|
return newImage, nil
|
|
}
|
|
|
|
func DeleteOldAvatarImage(userId string) error {
|
|
path := utils.GetUserStoragePath(userId)
|
|
|
|
dir, err := os.ReadDir(path)
|
|
|
|
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
gocnjhelper.LogErrorf("Failed to read dir, err: %s", err)
|
|
return err
|
|
}
|
|
|
|
for _, file := range dir {
|
|
os.Remove(path + file.Name())
|
|
}
|
|
|
|
return nil
|
|
}
|