Docker/Voltaserve/conversion/processor/image_processor.go
2024-04-17 20:22:30 +02:00

138 lines
3.6 KiB
Go

package processor
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"voltaserve/client"
"voltaserve/config"
"voltaserve/core"
"voltaserve/helper"
"voltaserve/identifier"
"voltaserve/infra"
)
type ImageProcessor struct {
apiClient *client.APIClient
fileIdent *identifier.FileIdentifier
config config.Config
}
func NewImageProcessor() *ImageProcessor {
return &ImageProcessor{
apiClient: client.NewAPIClient(),
fileIdent: identifier.NewFileIdentifier(),
config: config.GetConfig(),
}
}
func (p *ImageProcessor) Base64Thumbnail(inputPath string) (core.ImageBase64, error) {
inputSize, err := p.MeasureImage(inputPath)
if err != nil {
return core.ImageBase64{}, err
}
if inputSize.Width > p.config.Limits.ImagePreviewMaxWidth || inputSize.Height > p.config.Limits.ImagePreviewMaxHeight {
outputPath := filepath.FromSlash(os.TempDir() + "/" + helper.NewID() + filepath.Ext(inputPath))
if inputSize.Width > inputSize.Height {
if err := p.ResizeImage(inputPath, p.config.Limits.ImagePreviewMaxWidth, 0, outputPath); err != nil {
return core.ImageBase64{}, err
}
} else {
if err := p.ResizeImage(inputPath, 0, p.config.Limits.ImagePreviewMaxHeight, outputPath); err != nil {
return core.ImageBase64{}, err
}
}
b64, err := helper.ImageToBase64(outputPath)
if err != nil {
return core.ImageBase64{}, err
}
size, err := p.MeasureImage(outputPath)
if err != nil {
return core.ImageBase64{}, err
}
return core.ImageBase64{
Base64: b64,
Width: size.Width,
Height: size.Height,
}, nil
} else {
b64, err := helper.ImageToBase64(inputPath)
if err != nil {
return core.ImageBase64{}, err
}
size, err := p.MeasureImage(inputPath)
if err != nil {
return core.ImageBase64{}, err
}
return core.ImageBase64{
Base64: b64,
Width: size.Width,
Height: size.Height,
}, nil
}
}
func (p *ImageProcessor) MeasureImage(inputPath string) (core.ImageProps, error) {
size, err := infra.NewCommand().ReadOutput("identify", "-format", "%w,%h", inputPath)
if err != nil {
return core.ImageProps{}, err
}
values := strings.Split(size, ",")
width, err := strconv.Atoi(helper.RemoveNonNumeric(values[0]))
if err != nil {
return core.ImageProps{}, err
}
height, err := strconv.Atoi(helper.RemoveNonNumeric(values[1]))
if err != nil {
return core.ImageProps{}, err
}
return core.ImageProps{Width: width, Height: height}, nil
}
func (p *ImageProcessor) ResizeImage(inputPath string, width int, height int, outputPath string) error {
var widthStr string
if width == 0 {
widthStr = ""
} else {
widthStr = strconv.FormatInt(int64(width), 10)
}
var heightStr string
if height == 0 {
heightStr = ""
} else {
heightStr = strconv.FormatInt(int64(height), 10)
}
if err := infra.NewCommand().Exec("convert", "-resize", widthStr+"x"+heightStr, inputPath, outputPath); err != nil {
return err
}
return nil
}
func (p *ImageProcessor) ThumbnailFromImage(inputPath string, width int, height int, outputPath string) error {
var widthStr string
if width == 0 {
widthStr = ""
} else {
widthStr = strconv.FormatInt(int64(width), 10)
}
var heightStr string
if height == 0 {
heightStr = ""
} else {
heightStr = strconv.FormatInt(int64(height), 10)
}
if err := infra.NewCommand().Exec("convert", "-thumbnail", widthStr+"x"+heightStr, "-background", "white", "-alpha", "remove", "-flatten", fmt.Sprintf("%s[0]", inputPath), outputPath); err != nil {
return err
}
return nil
}
func (p *ImageProcessor) ConvertImage(inputPath string, outputPath string) error {
if err := infra.NewCommand().Exec("convert", inputPath, outputPath); err != nil {
return err
}
return nil
}