Files

65 lines
1.5 KiB
Go

package storage
import (
"bytes"
"fmt"
"image"
"image/png"
"io"
// Import image formats for decoding
_ "image/gif"
_ "image/jpeg"
"golang.org/x/image/draw"
)
// IconSizes defines the icon sizes to generate
var IconSizes = []int{32, 64, 128}
// ProcessIcon reads an image and generates icons at multiple sizes
func (s *Storage) ProcessIcon(appID string, r io.Reader) error {
// Decode the image
img, _, err := image.Decode(r)
if err != nil {
return fmt.Errorf("failed to decode image: %w", err)
}
// Validate square dimensions
bounds := img.Bounds()
if bounds.Dx() != bounds.Dy() {
return fmt.Errorf("icon must be square, got %dx%d", bounds.Dx(), bounds.Dy())
}
// Minimum size check
if bounds.Dx() < 128 {
return fmt.Errorf("icon must be at least 128x128, got %dx%d", bounds.Dx(), bounds.Dy())
}
// Generate each size
for _, size := range IconSizes {
resized := resizeImage(img, size, size)
var buf bytes.Buffer
if err := png.Encode(&buf, resized); err != nil {
return fmt.Errorf("failed to encode icon-%d: %w", size, err)
}
if err := s.SaveIcon(appID, size, buf.Bytes()); err != nil {
return fmt.Errorf("failed to save icon-%d: %w", size, err)
}
}
return nil
}
// resizeImage resizes an image to the specified dimensions using high-quality interpolation
func resizeImage(src image.Image, width, height int) image.Image {
dst := image.NewRGBA(image.Rect(0, 0, width, height))
// Use CatmullRom for high-quality downscaling
draw.CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), draw.Over, nil)
return dst
}