finstr/crop/crop.go

42 lines
1.2 KiB
Go
Raw Permalink Normal View History

2019-01-01 19:31:14 +01:00
package crop
import (
"errors"
"image"
2024-06-18 22:39:16 +02:00
goutil "git.fireandbrimst.one/aw/goutil/misc"
2019-01-01 19:31:14 +01:00
)
func boundInt(i, min, max int) int {
return goutil.IntMin(goutil.IntMax(i, min), max)
}
func bound(p image.Point, bounds image.Rectangle) image.Point {
min := bounds.Min
max := bounds.Max
return image.Point{X: boundInt(p.X, min.X, max.X), Y: boundInt(p.Y, min.Y, max.Y)}
}
type subImageSupport interface {
SubImage(rec image.Rectangle) image.Image
}
func Crop(img image.Image, topleft image.Point, w int, h int) (image.Image, error) {
bounds := img.Bounds()
topleft = bound(topleft, bounds)
bottomright := bound(image.Point{X: topleft.X + w, Y: topleft.Y + h}, bounds)
croparea := image.Rect(topleft.X, topleft.Y, bottomright.X, bottomright.Y)
if timg, ok := img.(subImageSupport); ok {
return timg.SubImage(croparea), nil
} else {
return nil, errors.New("Crop: image format does not support 'SubImage' method (cropping not supported)")
}
}
func CropCenter(img image.Image, w int, h int) (image.Image, error) {
bounds := img.Bounds()
center := image.Point{X: bounds.Min.X + bounds.Dx()/2, Y: bounds.Min.Y + bounds.Dy()/2}
topleft := image.Point{X: center.X - w/2, Y: center.Y - h/2}
return Crop(img, topleft, w, h)
}