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 } const ( DefaultQuality = 90 DefaultFormat = "avif" ) func NormalizeOptions(opts ProcessOptions) (ProcessOptions, error) { if opts.Width < 0 || opts.Height < 0 { return ProcessOptions{}, fmt.Errorf("width/height negatif olamaz") } if opts.Quality == 0 { opts.Quality = DefaultQuality } if opts.Quality < 1 || opts.Quality > 100 { return ProcessOptions{}, fmt.Errorf("quality 1-100 araliginda olmali") } format := strings.ToLower(strings.TrimSpace(opts.Format)) if format == "" { format = DefaultFormat } if format == "jpg" { format = "jpeg" } switch format { case "webp", "avif", "png", "jpeg": opts.Format = format default: return ProcessOptions{}, fmt.Errorf("desteklenmeyen format: %s", format) } return opts, nil } func ProcessImage(buffer []byte, opts ProcessOptions) ([]byte, error) { normalized, err := NormalizeOptions(opts) if err != nil { return nil, err } startTime := time.Now() img := bimg.NewImage(buffer) origSize, _ := img.Size() origType := img.Type() origKB := len(buffer) / 1024 options := bimg.Options{ Width: normalized.Width, Height: normalized.Height, Quality: normalized.Quality, } // Cover mode: Enlarge and crop to fill the dimensions if normalized.Cover { options.Crop = true options.Enlarge = true } format := normalized.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, normalized.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 } func GetSize(buffer []byte) (bimg.ImageSize, error) { img := bimg.NewImage(buffer) return img.Size() }