package util import ( "bytes" "image" "time" "gat1400Exchange/vo" "basic.com/pubsub/protomsg.git" "basic.com/valib/godraw.git" ) // 按尺寸去切图 func SubCutImg(srcImage []byte, rect *vo.Rect, enlarge int) ([]byte, error) { i, err := readFromUploadImg(srcImage) bkImg, _ := godraw.ToImage(srcImage, int(i.Width), int(i.Height)) newRect := EnlargeCut(rect, int(i.Width), int(i.Height), enlarge) squareRect := LetterBox(newRect, int(i.Width), int(i.Height)) rectNew := image.Rect(squareRect.Left, squareRect.Top, squareRect.Right, squareRect.Bottom) subImg := bkImg.(*image.RGBA).SubImage(rectNew) bytes, err := godraw.ImageToJpeg(subImg, nil) if err != nil { return nil, err } return bytes, nil } // letterbox 按照宽边修改目标框为正方形 func LetterBox(rect *vo.Rect, maxW, maxH int) *vo.Rect { width := rect.Right - rect.Left height := rect.Bottom - rect.Top // 计算目标框的中心点坐标 centerX := (rect.Left + rect.Right) / 2 centerY := (rect.Top + rect.Bottom) / 2 // 如果宽度大于高度,则以高度为基准调整宽度,使其成为正方形 if width > height { newWidth := height newLeft := centerX - newWidth/2 newRight := centerX + newWidth/2 // 调整后的正方形框超出图像边界时的处理 if newLeft < 0 { // 如果左边界超出,向右移动右边界 newRight += -newLeft newLeft = 0 } if newRight > maxW { // 如果右边界超出,向左移动左边界 newLeft -= newRight - maxW newRight = maxW } return &vo.Rect{ Left: newLeft, Top: rect.Top, Right: newRight, Bottom: rect.Bottom, } } // 如果高度大于宽度,则以宽度为基准调整高度,使其成为正方形 if height > width { newHeight := width newTop := centerY - newHeight/2 newBottom := centerY + newHeight/2 // 调整后的正方形框超出图像边界时的处理 if newTop < 0 { // 如果上边界超出,向下移动下边界 newBottom += -newTop newTop = 0 } if newBottom > maxH { // 如果下边界超出,向上移动上边界 newTop -= newBottom - maxH newBottom = maxH } return &vo.Rect{ Left: rect.Left, Top: newTop, Right: rect.Right, Bottom: newBottom, } } // 如果宽度和高度相等,则已经是正方形,直接返回原始矩形 return rect } // 长宽变为一比一,每边各扩百分之... func EnlargeCut(rect *vo.Rect, maxW, maxH int, enlargePer int) *vo.Rect { var x0New, x1New, y0New, y1New int // 先把长宽变为一比一 x0 := rect.Left y0 := rect.Top x1 := rect.Right y1 := rect.Bottom chaZhi := (y1 - y0) - (x1 - x0) if chaZhi > 0 { x0 = x0 - chaZhi/2 if x0 < 0 { x0 = 0 } x1 = x1 + chaZhi/2 if x1 > maxW { x1 = maxW } } else { y0 = y0 + chaZhi/2 if y0 < 0 { y0 = 0 } y1 = y1 - chaZhi/2 if y1 > maxH { y1 = maxH } } // 再把每边各扩大百分之... enlarge := float32(enlargePer) / 100 x0New = int((1+enlarge)*float32(x0) - enlarge*float32(x1)) if x0New < 0 { x0New = 0 } x1New = int((1+enlarge)*float32(x1) - enlarge*float32(x0)) if x1New > maxW { x1New = maxW } y0New = int((1+enlarge)*float32(y0) - enlarge*float32(y1)) if y0New < 0 { y0New = 0 } y1New = int((1+enlarge)*float32(y1) - enlarge*float32(y0)) if y1New > maxH { y1New = maxH } return &vo.Rect{ Left: x0New, Top: y0New, Right: y0New, Bottom: y1New, } } func readFromUploadImg(imageFile []byte) (*protomsg.Image, error) { bt := bytes.NewBuffer(imageFile) img, _, err := image.Decode(bt) if err != nil { return nil, err } bgr := godraw.Image2BGR(img) timeUnix := time.Now().Unix() formatTimeStr := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05") return &protomsg.Image{ Width: int32(img.Bounds().Dx()), Height: int32(img.Bounds().Dy()), Timestamp: formatTimeStr, Data: bgr, Id: time.Now().Unix(), Cid: "gat1400", }, nil }