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)
|
|
|
|
}
|