zhangzengfei
2024-04-18 1bc9b974469d6959c900b7a083fec2689e5cdd8e
添加根据坐标切小图的功能
2个文件已添加
4个文件已修改
298 ■■■■■ 已修改文件
go.mod 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
repository/captureRepo.go 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/imageTool.go 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vo/common.go 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vo/face.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod
@@ -18,6 +18,8 @@
)
require (
    basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3 // indirect
    basic.com/valib/godraw.git v0.0.0-20191122082247-26e9987cd183 // indirect
    github.com/bytedance/sonic v1.10.2 // indirect
    github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
    github.com/chenzhuoyu/iasm v0.9.1 // indirect
@@ -26,7 +28,10 @@
    github.com/go-co-op/gocron v1.37.0 // indirect
    github.com/go-sql-driver/mysql v1.7.0 // indirect
    github.com/goccy/go-json v0.10.2 // indirect
    github.com/gogo/protobuf v1.3.2 // indirect
    github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
    github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
    github.com/golang/protobuf v1.5.3 // indirect
    github.com/google/uuid v1.4.0 // indirect
    github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
    github.com/hashicorp/hcl v1.0.0 // indirect
@@ -35,6 +40,7 @@
    github.com/json-iterator/go v1.1.12 // indirect
    github.com/klauspost/cpuid/v2 v2.2.6 // indirect
    github.com/leodido/go-urn v1.4.0 // indirect
    github.com/llgcode/draw2d v0.0.0-20240322162412-ee6987bd01dc // indirect
    github.com/magiconair/properties v1.8.7 // indirect
    github.com/mattn/go-isatty v0.0.20 // indirect
    github.com/mattn/go-sqlite3 v1.14.17 // indirect
@@ -58,9 +64,12 @@
    golang.org/x/arch v0.7.0 // indirect
    golang.org/x/crypto v0.19.0 // indirect
    golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
    golang.org/x/image v0.14.0 // indirect
    golang.org/x/net v0.21.0 // indirect
    golang.org/x/sys v0.17.0 // indirect
    golang.org/x/text v0.14.0 // indirect
    google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
    google.golang.org/grpc v1.59.0 // indirect
    google.golang.org/protobuf v1.32.0 // indirect
    gopkg.in/ini.v1 v1.67.0 // indirect
    gopkg.in/yaml.v3 v3.0.1 // indirect
go.sum
@@ -1,3 +1,7 @@
basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3 h1:h6dF39g4oqEMY0wDcFG3W4wYpeTNFjwWMp8TmFKnrAg=
basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/valib/godraw.git v0.0.0-20191122082247-26e9987cd183 h1:QQ1L0Ev4vcSD23d99+rW5S/mnmdTAPAI2GZ7tkMgCE4=
basic.com/valib/godraw.git v0.0.0-20191122082247-26e9987cd183/go.mod h1:LntbWczdG87utrKx7rWYmIh1VZ+X2oPN7Q2IXb6oRE0=
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
github.com/appleboy/gin-jwt/v2 v2.9.2 h1:GeS3lm9mb9HMmj7+GNjYUtpp3V1DAQ1TkUFa5poiZ7Y=
@@ -42,8 +46,16 @@
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
@@ -60,6 +72,8 @@
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -74,6 +88,8 @@
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/llgcode/draw2d v0.0.0-20240322162412-ee6987bd01dc h1:lorg2FaIDdlahOHekjnQjItP2oCtkVlYc0QNekubCLk=
github.com/llgcode/draw2d v0.0.0-20240322162412-ee6987bd01dc/go.mod h1:muweRyJCZ1mZSMiCgYbAicfnwZFoeHpNr6A6QBu+rBg=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -133,6 +149,8 @@
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
@@ -140,18 +158,52 @@
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
repository/captureRepo.go
@@ -22,6 +22,8 @@
}
func (c CaptureRepository) FaceForward(faceList []vo.FaceObject) {
    var err error
    if faceList == nil || len(faceList) == 0 {
        logger.Warn("FaceList is nil")
        return
@@ -35,19 +37,42 @@
        var deviceId = face.DeviceID
        var faceId = face.FaceID
        var faceImageStr string
        var bgImageStr, imageType string
        var bgImageBytes, faceImageBytes []byte = nil, nil
        // 获取大图, 目前海康的小图分辨率太低
        for _, image := range face.SubImageList.SubImageInfoObject {
            if len(image.Data) > len(faceImageStr) {
                faceImageStr = image.Data
            if len(image.Data) > len(bgImageStr) {
                bgImageStr = image.Data
                imageType = image.Type
            }
        }
        bgImageBytes, err = base64.StdEncoding.DecodeString(bgImageStr)
        if err != nil {
            logger.Warn("Decode Image Base64 String failure, %s", err.Error())
            continue
        }
        // 判断图片类型是否为场景图, 根据人脸坐标切小图.
        if imageType == "14" {
            faceRect := &vo.Rect{
                Left:   face.LeftTopX,
                Top:    face.LeftTopY,
                Right:  face.RightBtmX,
                Bottom: face.RightBtmY,
            }
            faceImageBytes, err = util.SubCutImg(bgImageBytes, faceRect, 90)
            if err != nil {
                logger.Warn("Cut face image failure, %s", err.Error())
            }
        }
        // 转发图像
        logger.Debug("Prepare forward image, deviceId:%s, image len:%d, server:%s", deviceId, len(faceImageStr), config.ForwardConf.SyncServer)
        if deviceId != "" && faceImageStr != "" && config.ForwardConf.SyncServer != "" {
            pd := c.PackPushDataV2(deviceId, faceId, faceImageStr, face.FaceAppearTime)
        logger.Debug("Prepare forward image, deviceId:%s, image len:%d, server:%s", deviceId, len(bgImageStr), config.ForwardConf.SyncServer)
        if deviceId != "" && bgImageStr != "" && config.ForwardConf.SyncServer != "" {
            pd := c.PackPushDataV2(deviceId, faceId, face.FaceAppearTime, bgImageBytes, faceImageBytes)
            if pd == nil {
                return
            }
@@ -125,7 +150,7 @@
    return pd
}
func (c CaptureRepository) PackPushDataV2(deviceId, faceId, faceImage, appearTime string) *vo.PushDataInfoV2 {
func (c CaptureRepository) PackPushDataV2(deviceId, faceId, appearTime string, bgImgBytes, faceImgBytes []byte) *vo.PushDataInfoV2 {
    var pd = new(vo.PushDataInfoV2)
    var device models.Device
@@ -147,13 +172,12 @@
        devPos.Pos = device.Pos
    }
    imageBytes, err := base64.StdEncoding.DecodeString(faceImage)
    if err != nil {
        logger.Warn("Decode Image Base64 String failure, %s", err.Error())
        return pd
    pd.PicMaxImages = append(pd.PicMaxImages, bgImgBytes)
    if faceImgBytes != nil {
        pd.PicSmImages = append(pd.PicSmImages, faceImgBytes)
    }
    pd.PicMaxImages = append(pd.PicMaxImages, imageBytes)
    pd.PicId = faceId
    pd.PicDate = faceAppearTime.Format("2006-01-02 15:04:05")
    pd.DataSource = "camera"
util/imageTool.go
New file
@@ -0,0 +1,177 @@
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
}
vo/common.go
New file
@@ -0,0 +1,8 @@
package vo
type Rect struct {
    Left   int
    Top    int
    Right  int
    Bottom int
}
vo/face.go
@@ -4,8 +4,8 @@
    ImageID     string `json:"ImageID"`     // 图像ID
    EventSort   int    `json:"EventSort"`   // 事件排序
    DeviceID    string `json:"DeviceID"`    // 设备ID
    StoragePath string `json:"StoragePath"` // 存储路径
    Type        string `json:"Type"`        // 类型
    StoragePath string `json:"StoragePath"` // 存储路径 采用Data传图片时为空
    Type        string `json:"Type"`        // 类型 14 场景图, 11 人脸图
    FileFormat  string `json:"FileFormat"`  // 文件格式
    ShotTime    string `json:"ShotTime"`    // 拍摄时间
    Width       int    `json:"Width"`       // 宽度