代码
go源码包即可
代码:
// CropImage will get sub image on position
func CropImage(img image.Image, minX, maxX, minY, maxY int) image.Image {
// check range of position
if checkRect(minX, maxX, minY, maxY, img.Bounds()) {
return nil
}
// image in memory is image.YCbCr
rgbImg, ok := img.(*image.YCbCr)
if !ok {
return nil
}
return rgbImg.SubImage(image.Rect(minX, minY, maxX, maxY))
}
func checkRect(minX, maxX, minY, maxY int, r image.Rectangle) bool {
if maxX > r.Dx() || maxY > r.Dy() {
return false
}
return minX < 0 || minX >= maxX || minY < 0 || minY >= maxY
}
测试
你可以使用如下代码进行解码
import (
"bytes"
"image"
_ "image/jpeg" //对于需要解码的格式需要倒入包
_ "image/png"
"os"
"reflect"
"strings"
"testing"
)
func TestCropImage(t *testing.T) {
type args struct {
img image.Image
minX int
maxX int
minY int
maxY int
}
imgPath := GetCurrentPath() + "/testData/video-001.jpeg"
file, err := os.ReadFile(imgPath)
if err != nil {
return
}
buf := bytes.NewReader(file)
img, ext, err := image.Decode(buf)
if err != nil {
return
}
bound := img.Bounds()
t.Log("image:", ext)
tests := []struct {
name string
args args
want image.Image
}{
{"crop img", args{
img: img,
minX: 0,
maxX: bound.Dx() >> 1,
minY: 0,
maxY: bound.Dy() >> 1,
}, image.NewRGBA(image.Rect(0, 0, bound.Dx()>>1, bound.Dy()>>1))},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := CropImage(tt.args.img, tt.args.minX, tt.args.maxX, tt.args.minY, tt.args.maxY)
if !reflect.DeepEqual(got.Bounds(), tt.want.Bounds()) {
t.Errorf("CropImage() = %v, want %v", got, tt.want)
}
})
}
}
func GetCurrentPath() string {
dir, err := os.Getwd()
if err != nil {
return ""
}
return strings.Replace(dir, "\\", "/", -1)
}
主要原理
利用源码包的SubImage()可以实现,每一个Image对象都有这个方法