Files
Web_FaceValidator_Dev/Controllers/FaceFeatureController.cs
2025-11-26 11:14:33 +08:00

246 lines
8.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CliWrap;
using CliWrap.Buffered;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json.Serialization;
using static System.Net.Mime.MediaTypeNames;
using Newtonsoft.Json;
using BLV_API;
namespace FaceValidator.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class FaceFeatureController : ControllerBase
{
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly ILogger<FaceFeatureController> _logger;
public FaceFeatureController(
IWebHostEnvironment hostingEnvironment,
ILogger<FaceFeatureController> logger)
{
_hostingEnvironment = hostingEnvironment;
_logger = logger;
}
/// <summary>
/// 提交人脸Url/File
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> ValidateFaceVal([FromForm] UploadFileModel data)
{
try
{
var file = data.File;
var faceUrl = data.FaceUrl;
// 检查输入是否有效
if (file == null && string.IsNullOrWhiteSpace(faceUrl))
{
return BadRequest("必须提供图片文件或图片URL");
}
// 保存图片到本地临时文件
string tempImagePath;
if (file != null)
{
//
tempImagePath = await SaveUploadedFileAsync(file);
}
else
{
tempImagePath = await DownloadImageAsync(faceUrl);
}
// 调用验证方法
var validationResult = await FaceValidator(tempImagePath);
// 清理临时文件
//System.IO.File.Delete(tempImagePath);
return validationResult;
}
catch (Exception ex)
{
_logger.LogError(ex, "人脸验证过程中发生未处理异常");
return StatusCode(500, $"系统错误: {ex.Message}");
}
}
private async Task<string> SaveUploadedFileAsync(IFormFile file)
{
var tempFileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
var tempFilePath = Path.Combine(_hostingEnvironment.ContentRootPath, "wwwroot/upload", tempFileName);
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
using (var stream = new FileStream(tempFilePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return tempFilePath;
}
private async Task<string> DownloadImageAsync(string faceUrl)
{
if (!Uri.TryCreate(faceUrl, UriKind.Absolute, out var uri))
{
throw new ArgumentException("提供的图片URL无效");
}
HttpClient httpClient = new();
var response = await httpClient.GetAsync(uri);
if (!response.IsSuccessStatusCode)
{
throw new ApplicationException($"无法下载图片: {response.StatusCode}");
}
var tempFileName = $"{Guid.NewGuid()}.jpg";
var tempFilePath = Path.Combine(_hostingEnvironment.ContentRootPath, "wwwroot/upload", tempFileName);
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(tempFilePath));
await using (var fs = new FileStream(tempFilePath, FileMode.Create))
await using (var stream = await response.Content.ReadAsStreamAsync())
{
await stream.CopyToAsync(fs);
}
return tempFilePath;
}
[HttpPost]
public async Task<IActionResult> FaceValidator(string localImagePath)
{
// 1. 错误处理:确保参数不为空
if (string.IsNullOrWhiteSpace(localImagePath))
{
return BadRequest("脸部数据参数不能为空");
}
// 2. 确保图片文件存在
if (!System.IO.File.Exists(localImagePath))
{
return BadRequest($"本地图片文件不存在: {localImagePath}");
}
// 3. 使用绝对路径确保可靠性
var exePath = Path.Combine(_hostingEnvironment.ContentRootPath, "ValRel", "faceidtest.exe");
var exeDirectory = Path.GetDirectoryName(exePath);
// 4. 检查可执行文件是否存在
if (!System.IO.File.Exists(exePath))
{
_logger.LogError($"可执行文件不存在: {exePath}");
return StatusCode(500, $"人脸验证程序未找到");
}
try
{
var stdOutBuffer = new StringBuilder();
var stdErrBuffer = new StringBuilder();
// 传递文件路径作为参数
var arguments = $"{localImagePath} 80x v3";
_logger.LogInformation($"执行人脸验证: {exePath} {arguments}");
// 创建取消令牌源并设置超时例如20秒
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20));
var result = await Cli.Wrap(exePath) // 指定可执行文件
.WithArguments(arguments) // 传递参数
.WithWorkingDirectory(exeDirectory) // 在exe所在目录执行
.WithValidation(CommandResultValidation.None) // 退出条件
.WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOutBuffer)) // 打印结果日志
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) // 打印过程日志
.ExecuteAsync(cts.Token); // 设置取消令牌
var fullOutput = stdErrBuffer.ToString();
fullOutput += stdOutBuffer.ToString();
string[] lines = fullOutput.Split(["\r\n", "\r", "\n"], StringSplitOptions.None);
var validationResult = "";
_logger.LogInformation($"结果: {fullOutput}");
var name = "";
foreach (var item in lines)
{
if (item.IndexOf("quality:") > -1)
{
validationResult = item.Split(":")[2].Trim();
break;
}
}
var vurl = "http://blv-rd.tech:19099/upload/";
//var vurl = "http://piccheck.blv-oa.com/upload/";
//D:\\AFace\\wwwroot/upload\\d7d5f295-8c75-4308-b36a-367c650a8ac4.jpg
vurl += Path.GetFileName(localImagePath);
LogHelper.WriteLog("图片名称:" + Path.GetFileName(localImagePath) + $" 验证结果: {validationResult}");
if (double.TryParse(validationResult, out double validationResultNum))
{
return Ok(new
{
Success = true,
Result = result,
ExitCode = 200,
quality = validationResultNum,
Url = vurl,
});
}
else
{
return Ok(new
{
Success = false,
Result = result,
ExitCode = 200,
Msg = "验证错误",
Url = vurl,
});
}
}
catch (OperationCanceledException)
{
_logger.LogError("操作超时,人脸验证未完成");
return StatusCode(504, "验证超时");
}
catch (Exception ex)
{
_logger.LogError(ex, "人脸验证过程中发生未处理异常");
return StatusCode(500, $"系统错误: {ex.Message}");
}
}
}
public class UploadFileModel
{
public IFormFile? File { get; set; }
public string? FaceUrl { get; set; }
}
public class ResultClass
{
public bool Success { get; set; }
public string? Result { get; set; }
public int Code { get; set; }
public string? Msg { get; set; }
}
}