2025-06-06 16:00:39 +08:00
|
|
|
|
using AlibabaCloud.SDK.Facebody20191230.Models;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Tea;
|
|
|
|
|
using VOL.Core.Configuration;
|
|
|
|
|
using static AlibabaCloud.SDK.Facebody20191230.Models.SearchFaceResponseBody.SearchFaceResponseBodyData.SearchFaceResponseBodyDataMatchList;
|
|
|
|
|
|
|
|
|
|
namespace VOL.Core.Utilities
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 阿里云Face
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ALiYunFace
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取 Client
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static AlibabaCloud.SDK.Facebody20191230.Client CreateClient()
|
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
|
|
|
|
|
{
|
|
|
|
|
AccessKeyId = AppSetting.ALiYunFaceDetect.AccessKeyId,
|
|
|
|
|
AccessKeySecret = AppSetting.ALiYunFaceDetect.SecretAccessKey,
|
|
|
|
|
Endpoint = AppSetting.ALiYunFaceDetect.Endpoint
|
|
|
|
|
};
|
|
|
|
|
return new AlibabaCloud.SDK.Facebody20191230.Client(config);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加人脸样本
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="schoolCode"></param>
|
|
|
|
|
/// <param name="entityId"></param>
|
|
|
|
|
/// <param name="isStudent"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
public static async Task<bool> FaceEntityWith(FaceEntityWithDto faceEntityWithDto)
|
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.SDK.Facebody20191230.Client client = CreateClient();
|
|
|
|
|
AddFaceEntityRequest addFaceEntityRequest = new AddFaceEntityRequest()
|
|
|
|
|
{
|
|
|
|
|
EntityId = faceEntityWithDto.EntityId,
|
|
|
|
|
Labels = faceEntityWithDto.SchoolCode,
|
|
|
|
|
DbName = faceEntityWithDto.IsStudent ? AppSetting.ALiYunFaceDetect.StudeneDb : AppSetting.ALiYunFaceDetect.TeacherDb
|
|
|
|
|
};
|
|
|
|
|
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var res = await client.AddFaceEntityWithOptionsAsync(addFaceEntityRequest, runtime);
|
|
|
|
|
return res != null;
|
|
|
|
|
}
|
|
|
|
|
catch (TeaException error)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception _error)
|
|
|
|
|
{
|
|
|
|
|
TeaException error = new TeaException(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ "message", _error.Message }
|
|
|
|
|
});
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 删除人脸样本
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="faceEntityWithDto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
public static async Task<bool> DeleteFaceEntityWith(FaceEntityWithDto faceEntityWithDto)
|
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.SDK.Facebody20191230.Client client = CreateClient();
|
|
|
|
|
DeleteFaceEntityRequest deleteFaceEntityRequest = new DeleteFaceEntityRequest()
|
|
|
|
|
{
|
|
|
|
|
EntityId = faceEntityWithDto.EntityId,
|
|
|
|
|
DbName = faceEntityWithDto.IsStudent ? AppSetting.ALiYunFaceDetect.StudeneDb : AppSetting.ALiYunFaceDetect.TeacherDb
|
|
|
|
|
};
|
|
|
|
|
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var res = await client.DeleteFaceEntityWithOptionsAsync(deleteFaceEntityRequest, runtime);
|
|
|
|
|
return res != null;
|
|
|
|
|
}
|
|
|
|
|
catch (TeaException error)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception _error)
|
|
|
|
|
{
|
|
|
|
|
TeaException error = new TeaException(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ "message", _error.Message }
|
|
|
|
|
});
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加人脸数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="schoolCode"></param>
|
|
|
|
|
/// <param name="entityId"></param>
|
|
|
|
|
/// <param name="isStudent"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
public static async Task<bool> FaceWith(FaceWithDto faceWithDto)
|
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.SDK.Facebody20191230.Client client = CreateClient();
|
|
|
|
|
AddFaceRequest addFaceRequest = new AddFaceRequest()
|
|
|
|
|
{
|
|
|
|
|
EntityId = faceWithDto.EntityId,
|
|
|
|
|
ExtraData = faceWithDto.Name,
|
|
|
|
|
ImageUrl = faceWithDto.ImageUrl,
|
|
|
|
|
DbName = faceWithDto.IsStudent ? AppSetting.ALiYunFaceDetect.StudeneDb : AppSetting.ALiYunFaceDetect.TeacherDb
|
|
|
|
|
};
|
|
|
|
|
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var res = await client.AddFaceWithOptionsAsync(addFaceRequest, runtime);
|
|
|
|
|
return res != null;
|
|
|
|
|
}
|
|
|
|
|
catch (TeaException error)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception($"人脸数据添加失败:请检查图片内容是否符合要求。确保图片中包含清晰无遮挡的人脸,并且图片分辨率符合要求(建议 640x480 或更高),文件大小不超过 2MB。错误详情:{error.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception _error)
|
|
|
|
|
{
|
|
|
|
|
TeaException error = new TeaException(new Dictionary<string, object>
|
2025-06-06 16:55:14 +08:00
|
|
|
|
{
|
|
|
|
|
{ "message", _error.Message }
|
|
|
|
|
});
|
2025-06-06 16:00:39 +08:00
|
|
|
|
throw new Exception($"系统异常:人脸数据添加失败。可能原因包括图片格式或内容不符合要求。请确保图片为正面人脸清晰无遮挡,分辨率不少于 640x480,大小不超过 2MB。错误详情:{error.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 搜索人脸
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="faceDbName"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-06-06 16:55:14 +08:00
|
|
|
|
public static async Task<SearchFaceResponseBodyDataMatchListFaceItems> SearchFace(string base64, bool isStudent = true)
|
2025-06-06 16:00:39 +08:00
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.SDK.Facebody20191230.Client client = CreateClient();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string pattern = @"^(\s*data\s*:\s*)?image\s*/\s*(png|jgp|jpg|jpeg)\s*;\s*base64\s*,";
|
|
|
|
|
string cleanBase64Str = Regex.Replace(base64, pattern, "", RegexOptions.IgnoreCase);
|
|
|
|
|
|
|
|
|
|
byte[] imageBytes = Convert.FromBase64String(cleanBase64Str);
|
|
|
|
|
|
|
|
|
|
using (var stream = new MemoryStream(imageBytes))
|
|
|
|
|
{
|
|
|
|
|
var searchFaceAdvanceRequest = new SearchFaceAdvanceRequest
|
|
|
|
|
{
|
|
|
|
|
ImageUrlObject = stream,
|
2025-06-06 16:55:14 +08:00
|
|
|
|
Limit = 1,
|
2025-06-06 16:00:39 +08:00
|
|
|
|
DbName = isStudent ? AppSetting.ALiYunFaceDetect.StudeneDb : AppSetting.ALiYunFaceDetect.TeacherDb
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
|
|
|
|
|
|
|
|
|
var res = await client.SearchFaceAdvanceAsync(searchFaceAdvanceRequest, runtime);
|
|
|
|
|
|
2025-06-06 16:55:14 +08:00
|
|
|
|
return res.Body.Data.MatchList.Count > 0 && res.Body.Data.MatchList[0].FaceItems.Count > 0 ? res.Body.Data.MatchList[0].FaceItems[0] : null;
|
2025-06-06 16:00:39 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (TeaException error)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception _error)
|
|
|
|
|
{
|
|
|
|
|
TeaException error = new TeaException(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ "message", _error.Message }
|
|
|
|
|
});
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 搜索人脸
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="faceDbName"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static async Task<SearchFaceResponseBodyDataMatchListFaceItems> SearchFace(IFormFile formFile, bool isStudent = true)
|
|
|
|
|
{
|
|
|
|
|
AlibabaCloud.SDK.Facebody20191230.Client client = CreateClient();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var stream = formFile.OpenReadStream())
|
|
|
|
|
{
|
|
|
|
|
var searchFaceAdvanceRequest = new SearchFaceAdvanceRequest
|
|
|
|
|
{
|
|
|
|
|
ImageUrlObject = stream,
|
|
|
|
|
Limit = 1,
|
|
|
|
|
DbName = isStudent ? AppSetting.ALiYunFaceDetect.StudeneDb : AppSetting.ALiYunFaceDetect.TeacherDb
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
|
|
|
|
|
|
|
|
|
var res = await client.SearchFaceAdvanceAsync(searchFaceAdvanceRequest, runtime);
|
|
|
|
|
|
|
|
|
|
return res.Body.Data.MatchList.Count > 0 && res.Body.Data.MatchList[0].FaceItems.Count > 0 ? res.Body.Data.MatchList[0].FaceItems[0] : null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (TeaException error)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception _error)
|
|
|
|
|
{
|
|
|
|
|
TeaException error = new TeaException(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ "message", _error.Message }
|
|
|
|
|
});
|
|
|
|
|
throw new Exception(error.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class FaceEntityWithDto
|
|
|
|
|
{
|
|
|
|
|
public bool IsStudent { get; set; }
|
|
|
|
|
|
|
|
|
|
public string SchoolCode { get; set; }
|
|
|
|
|
|
|
|
|
|
public string EntityId { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class FaceWithDto : FaceEntityWithDto
|
|
|
|
|
{
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
public string ImageUrl { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|