status-go/images/manipulation.go

80 lines
2.2 KiB
Go
Raw Normal View History

package images
import (
"fmt"
"image"
"math"
"github.com/nfnt/resize"
"github.com/oliamb/cutter"
2020-12-09 16:51:32 +00:00
"github.com/ethereum/go-ethereum/log"
)
2020-10-22 15:59:01 +00:00
func Resize(size ResizeDimension, img image.Image) image.Image {
2020-10-09 20:42:26 +00:00
var width, height uint
2020-10-27 14:42:42 +00:00
switch {
2020-10-09 20:42:26 +00:00
case img.Bounds().Max.X == img.Bounds().Max.Y:
2020-10-22 15:59:01 +00:00
width, height = uint(size), uint(size)
2020-10-09 20:42:26 +00:00
case img.Bounds().Max.X > img.Bounds().Max.Y:
2020-10-22 15:59:01 +00:00
width, height = 0, uint(size)
2020-10-09 20:42:26 +00:00
default:
2020-10-22 15:59:01 +00:00
width, height = uint(size), 0
2020-10-09 20:42:26 +00:00
}
2020-12-16 18:34:58 +00:00
log.Info("resizing", "size", size, "width", width, "height", height)
2020-12-09 16:51:32 +00:00
return resize.Resize(width, height, img, resize.Bilinear)
}
func ShrinkOnly(size ResizeDimension, img image.Image) image.Image {
finalSize := int(math.Min(float64(size), math.Min(float64(img.Bounds().Dx()), float64(img.Bounds().Dy()))))
return Resize(ResizeDimension(finalSize), img)
}
func Crop(img image.Image, rect image.Rectangle) (image.Image, error) {
2020-10-27 14:42:42 +00:00
if img.Bounds().Max.X < rect.Max.X || img.Bounds().Max.Y < rect.Max.Y {
return nil, fmt.Errorf(
"crop dimensions out of bounds of image, image width '%dpx' & height '%dpx'; crop bottom right coordinate at X '%dpx' Y '%dpx'",
img.Bounds().Max.X, img.Bounds().Max.Y,
rect.Max.X, rect.Max.Y,
)
}
return cutter.Crop(img, cutter.Config{
Width: rect.Dx(),
Height: rect.Dy(),
Anchor: rect.Min,
})
}
// CropImage takes an image, usually downloaded from a URL
// If the image is square, the full image is returned
// It the image is rectangular, the largest central square is returned
// calculations at _docs/image-center-crop-calculations.png
func CropCenter(img image.Image) (image.Image, error) {
var cropRect image.Rectangle
maxBounds := img.Bounds().Max
if maxBounds.X == maxBounds.Y {
return img, nil
}
if maxBounds.X > maxBounds.Y {
// the final output should be YxY
cropRect = image.Rectangle{
Min: image.Point{X: maxBounds.X/2 - maxBounds.Y/2, Y: 0},
Max: image.Point{X: maxBounds.X/2 + maxBounds.Y/2, Y: maxBounds.Y},
}
} else {
// the final output should be XxX
cropRect = image.Rectangle{
Min: image.Point{X: 0, Y: maxBounds.Y/2 - maxBounds.X/2},
Max: image.Point{X: maxBounds.X, Y: maxBounds.Y/2 + maxBounds.X/2},
}
}
return Crop(img, cropRect)
}