73 lines
1.5 KiB
Go
73 lines
1.5 KiB
Go
package images
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/h2non/bimg"
|
|
)
|
|
|
|
type ProcessOptions struct {
|
|
Width int
|
|
Height int
|
|
Quality int
|
|
Format string // webp, avif, png, jpg, jpeg
|
|
Cover bool
|
|
}
|
|
|
|
func ProcessImage(buffer []byte, opts ProcessOptions) ([]byte, error) {
|
|
startTime := time.Now()
|
|
img := bimg.NewImage(buffer)
|
|
|
|
origSize, _ := img.Size()
|
|
origType := img.Type()
|
|
origKB := len(buffer) / 1024
|
|
|
|
options := bimg.Options{
|
|
Width: opts.Width,
|
|
Height: opts.Height,
|
|
Quality: opts.Quality,
|
|
}
|
|
|
|
if opts.Quality == 0 {
|
|
options.Quality = 85
|
|
}
|
|
|
|
// Cover mode: Enlarge and crop to fill the dimensions
|
|
if opts.Cover {
|
|
options.Crop = true
|
|
options.Enlarge = true
|
|
}
|
|
|
|
format := strings.ToLower(opts.Format)
|
|
switch format {
|
|
case "webp":
|
|
options.Type = bimg.WEBP
|
|
case "avif":
|
|
options.Type = bimg.AVIF
|
|
case "png":
|
|
options.Type = bimg.PNG
|
|
case "jpg", "jpeg":
|
|
options.Type = bimg.JPEG
|
|
}
|
|
|
|
log.Printf("[IMAGE-PROCESS-START] Original: %dx%d (%s, %dKB). Target -> W:%d, H:%d, Q:%d, Format:%v, Cover:%v",
|
|
origSize.Width, origSize.Height, origType, origKB,
|
|
options.Width, options.Height, options.Quality, options.Type, opts.Cover)
|
|
|
|
newImage, err := img.Process(options)
|
|
if err != nil {
|
|
log.Printf("[IMAGE-PROCESS-ERROR] Failed after %v: %v", time.Since(startTime), err)
|
|
return nil, fmt.Errorf("failed to process image: %w", err)
|
|
}
|
|
|
|
newKB := len(newImage) / 1024
|
|
diff := origKB - newKB
|
|
|
|
log.Printf("[IMAGE-PROCESS-DONE] Success in %v! New Size: %dKB (Difference: %dKB)", time.Since(startTime), newKB, diff)
|
|
|
|
return newImage, nil
|
|
}
|