From e554d048c9162c561d463023e6babeecf9a94fba Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 24 Aug 2022 21:06:27 +0300 Subject: [PATCH] Pad images when converting to webp --- portal.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/portal.go b/portal.go index b7e6ecf..0838366 100644 --- a/portal.go +++ b/portal.go @@ -24,6 +24,7 @@ import ( "fmt" "html" "image" + "image/color" _ "image/gif" "image/jpeg" "image/png" @@ -2814,12 +2815,45 @@ func (portal *Portal) convertWebPtoPNG(webpImage []byte) ([]byte, error) { return pngBuffer.Bytes(), nil } +type PaddedImage struct { + image.Image + Size int + OffsetX int + OffsetY int +} + +func (img *PaddedImage) Bounds() image.Rectangle { + return image.Rect(0, 0, img.Size, img.Size) +} + +func (img *PaddedImage) At(x, y int) color.Color { + return img.Image.At(x+img.OffsetX, y+img.OffsetY) +} + func (portal *Portal) convertToWebP(img []byte) ([]byte, error) { webpDecoded, _, err := image.Decode(bytes.NewReader(img)) if err != nil { return nil, fmt.Errorf("failed to decode image: %w", err) } + bounds := webpDecoded.Bounds() + width, height := bounds.Dx(), bounds.Dy() + if width != height { + paddedImg := &PaddedImage{ + Image: webpDecoded, + OffsetX: bounds.Min.Y, + OffsetY: bounds.Min.X, + } + if width > height { + paddedImg.Size = width + paddedImg.OffsetY -= (paddedImg.Size - height) / 2 + } else { + paddedImg.Size = height + paddedImg.OffsetX -= (paddedImg.Size - width) / 2 + } + webpDecoded = paddedImg + } + var pngBuffer bytes.Buffer if err = webp.Encode(&pngBuffer, webpDecoded, nil); err != nil { return nil, fmt.Errorf("failed to encode png image: %w", err)