Files
schreifuchs.ch/internal/components/gallery/controller.go
T
schreifuchs 763163c24e
/ publish (push) Successful in 4m4s
feat: image gallery (#2)
Reviewed-on: #2
2026-06-01 14:07:50 +02:00

87 lines
1.8 KiB
Go

package gallery
import (
"context"
"math"
"github.com/InfinityTools/go-binpack2d"
)
type Gallery struct {
GridWith int
GridHeight int
Images []Image
}
type Set struct {
SM Gallery
LG Gallery
XLG Gallery
}
func (s *Service) GetGallerySet(ctx context.Context) (gallerySet Set, err error) {
gallerySet.SM, err = s.GetGallery(ctx, 50)
if err != nil {
return
}
gallerySet.LG, err = s.GetGallery(ctx, 80)
if err != nil {
return
}
gallerySet.XLG, err = s.GetGallery(ctx, 120)
if err != nil {
return
}
return
}
func (s *Service) GetGallery(ctx context.Context, width int) (gallery Gallery, err error) {
imgs, err := s.GetImages(ctx)
if err != nil {
return
}
packer := binpack2d.Create(width, 999999)
for len(imgs) > 0 {
unused := make([]Image, 0, len(imgs))
for _, img := range imgs {
adjustImageSize(&img, 200)
rect, ok := packer.Insert(img.Width, img.Height, binpack2d.RULE_BEST_SHORT_SIDE_FIT)
if !ok {
unused = append(unused, img)
continue
}
img.X = rect.X
img.Y = rect.Y
gallery.Images = append(gallery.Images, img)
}
imgs = unused
}
packer.ShrinkBin(false)
gallery.GridHeight = packer.GetHeight()
gallery.GridWith = packer.GetWidth()
return
}
// adjustImageSize adjusts the image size so that the aspect ratio stays the same
// but the image area is the given parameter.
func adjustImageSize(img *Image, area int) {
// Calculate the original aspect ratio (W / H)
aspectRatio := float64(img.Width) / float64(img.Height)
// Calculate new height and width using the derived formulas
newHeight := math.Sqrt(float64(area) / aspectRatio)
newWidth := newHeight * aspectRatio
// Round to the nearest integer to minimize precision loss
img.Width = int(math.Round(newWidth))
img.Height = int(math.Round(newHeight))
}