feat(api): 添加图像处理配置和服务器端图像处理功能

- 新增 CompressionConfig、ThumbnailConfig 和 ImageProcessingConfig 结构体用于图像处理配置
- 实现 GetEffectiveConfig 方法提供图像处理配置的默认值
- 在 UploadConfig 中添加 ImageProcessing 字段传递服务器配置
- 移除客户端本地缩略图生成功能,改用服务器端处理
- 添加 UploadFaceDataWithProcessing 函数实现带图像处理的上传流程
- 实现 configToImageOptions 函数将服务器配置转换为图像处理选项
- 在 util/image.go 中添加完整的图像处理功能,支持裁切和缩放模式
- 更新依赖添加 golang.org/x/image 用于高质量图像缩放
- 添加 .claude 到 .gitignore 文件
This commit is contained in:
2025-12-30 11:51:17 +08:00
parent 669ae42051
commit 0b42dad969
7 changed files with 368 additions and 78 deletions

View File

@@ -3,7 +3,6 @@ package api
import (
"ZhenTuLocalPassiveAdapter/config"
"ZhenTuLocalPassiveAdapter/logger"
"ZhenTuLocalPassiveAdapter/util"
"context"
"encoding/base64"
"io"
@@ -177,32 +176,21 @@ func HandleUploadFaces(c *gin.Context) {
pos.RightBtmY = *face.RightBtmY
}
// 3. Generate Thumbnail (if Source Image and Coordinates exist)
var thumbImg []byte
if len(srcImg) > 0 && pos.LeftTopX > 0 && pos.LeftTopY > 0 { // Basic validation
// Use Source Image to generate thumbnail
// The thumbnail is 1/2 original size, centered on face
var err error
thumbImg, err = util.GenerateThumbnailFromCoords(srcImg, pos.LeftTopX, pos.LeftTopY, pos.RightBtmX, pos.RightBtmY)
if err != nil {
logger.Error("Failed to generate thumbnail", zap.String("faceId", face.FaceID), zap.Error(err))
// Continue without thumbnail? or fail?
// Usually continue, but log error.
}
}
// 3. Construct Face Rectangle for image processing
faceRect := [4]int{pos.LeftTopX, pos.LeftTopY, pos.RightBtmX, pos.RightBtmY}
// 4. Execute Upload Flow
// 4. Execute Upload Flow with Server-side Image Processing Configuration
scenicId := config.Config.Viid.ScenicId
go func(fID, dID string, fData, tData, sData []byte, p FacePositionInfo) {
go func(fID, dID string, fData, sData []byte, rect [4]int, p FacePositionInfo) {
// Create a detached context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
if err := UploadFaceData(ctx, scenicId, dID, fData, tData, sData, p); err != nil {
if err := UploadFaceDataWithProcessing(ctx, scenicId, dID, fData, sData, rect, p); err != nil {
logger.Error("Failed to process face upload", zap.String("faceId", fID), zap.Error(err))
}
}(face.FaceID, deviceID, faceImg, thumbImg, srcImg, pos)
}(face.FaceID, deviceID, faceImg, srcImg, faceRect, pos)
}
// Respond Success