80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package imageproc
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
|
|
xdraw "golang.org/x/image/draw"
|
|
)
|
|
|
|
func Crop(src image.Image, rect image.Rectangle) image.Image {
|
|
b := src.Bounds()
|
|
rect = rect.Intersect(b)
|
|
if rect.Empty() {
|
|
rect = b
|
|
}
|
|
dst := image.NewRGBA(image.Rect(0, 0, rect.Dx(), rect.Dy()))
|
|
for y := rect.Min.Y; y < rect.Max.Y; y++ {
|
|
for x := rect.Min.X; x < rect.Max.X; x++ {
|
|
dst.Set(x-rect.Min.X, y-rect.Min.Y, src.At(x, y))
|
|
}
|
|
}
|
|
return dst
|
|
}
|
|
|
|
func ResizeToMax(src image.Image, maxDim int) image.Image {
|
|
if maxDim <= 0 {
|
|
return src
|
|
}
|
|
b := src.Bounds()
|
|
w, h := b.Dx(), b.Dy()
|
|
if w <= maxDim && h <= maxDim {
|
|
return normalizeRGBA(src)
|
|
}
|
|
nw, nh := w, h
|
|
if w >= h {
|
|
nw = maxDim
|
|
nh = max(1, h*maxDim/w)
|
|
} else {
|
|
nh = maxDim
|
|
nw = max(1, w*maxDim/h)
|
|
}
|
|
dst := image.NewRGBA(image.Rect(0, 0, nw, nh))
|
|
xdraw.CatmullRom.Scale(dst, dst.Bounds(), src, b, xdraw.Over, nil)
|
|
return dst
|
|
}
|
|
|
|
func ResizeToFill(src image.Image, width, height int) image.Image {
|
|
if width <= 0 || height <= 0 {
|
|
return normalizeRGBA(src)
|
|
}
|
|
b := src.Bounds()
|
|
srcRatio := float64(b.Dx()) / float64(b.Dy())
|
|
dstRatio := float64(width) / float64(height)
|
|
crop := b
|
|
if srcRatio > dstRatio {
|
|
cropW := int(float64(b.Dy()) * dstRatio)
|
|
x0 := b.Min.X + (b.Dx()-cropW)/2
|
|
crop = image.Rect(x0, b.Min.Y, x0+cropW, b.Max.Y)
|
|
} else if srcRatio < dstRatio {
|
|
cropH := int(float64(b.Dx()) / dstRatio)
|
|
y0 := b.Min.Y + (b.Dy()-cropH)/2
|
|
crop = image.Rect(b.Min.X, y0, b.Max.X, y0+cropH)
|
|
}
|
|
dst := image.NewRGBA(image.Rect(0, 0, width, height))
|
|
xdraw.CatmullRom.Scale(dst, dst.Bounds(), src, crop, xdraw.Over, nil)
|
|
return dst
|
|
}
|
|
|
|
func normalizeRGBA(src image.Image) image.Image {
|
|
b := src.Bounds()
|
|
dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
|
|
xdraw.Draw(dst, dst.Bounds(), src, b.Min, xdraw.Src)
|
|
return dst
|
|
}
|
|
|
|
func rgba8(c color.Color) (int, int, int) {
|
|
r, g, b, _ := c.RGBA()
|
|
return int(r >> 8), int(g >> 8), int(b >> 8)
|
|
}
|