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