using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Net.Http.Headers; using MeterVision.Config; using System.Drawing; namespace MeterVision.RemoteApi { //识别时传入的数据(目前无用) public class MetaData { public int Width { get; set; } public int Height { get; set; } public int Size { get; set; } public MetaData() { Width = 320; Height = 240; Size = 0; } } public class ApiResponse { public int StatusCode { get; set; } public string ResponseBody { get; set; } public bool IsSuccess => StatusCode >= 200 && StatusCode < 300; } //返回的Response中的对象 public class RecognResult { public int result { get; set; } // 1=成功, 0=失败 public T data { get; set; } // 泛型数据部分 public string message { get; set; } // 提示信息 } //ApiResponse中的数据对象 public class RecognData { //没有识别出水表类别:0 //数字+指针水表:1 //全数字水表:2 //全指针水表:3 //压力表类型: 5 //水表没有摆正的图片:88 //只要有一个数字的概率低于50%:90 public int? meter_type { get; set; } //水表类型 public string image { get; set; } // base64 编码图像 public string logs { get; set; } // base64 编码日志 public double? reading { get; set; } // 数值 // 可扩展字段,如: // public string timestamp { get; set; } public double? reading_unit { get; set; } //读数单位 } //调用结果对象 public class CallApiResult { public int callResult { get; set; } //1:调用成功,0:调用时出错 public string errorMessage { get; set; } //调用出错时的错误消息 //调用成功时的返回对象 public RecognResult recognResult { get; set; } } //识别接口 public class RecogApi { //设置超时时间5秒 private static readonly HttpClient _client = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }; //调用识别 public static async Task CallRecogn(string imagePath,MetaData metadata) { //判断凸显尺寸是否合规 if (!ThisApp.IsImageDimensionsValid(imagePath)) { return new CallApiResult { callResult = 0, errorMessage = $"{imagePath}图像尺寸不合规", recognResult = null }; } try { string _url = CfginiItem.GetConfigItem().HttpApi; var metadataJson = JsonConvert.SerializeObject(metadata); using (var form = new MultipartFormDataContent()) using (var fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var imageContent = new StreamContent(fs)) { imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); form.Add(imageContent, "image", Path.GetFileName(imagePath)); var metadataContent = new StringContent(metadataJson, Encoding.UTF8, "application/json"); form.Add(metadataContent, "metadata"); //HttpResponseMessage response = _client.PostAsync(_url, form).GetAwaiter().GetResult(); HttpResponseMessage response = await _client.PostAsync(_url, form); if (!response.IsSuccessStatusCode) { return new CallApiResult { callResult = 0, errorMessage = $"接口返回错误:{(int)response.StatusCode} - {response.ReasonPhrase}", recognResult = null }; } string responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //解析JSON响应体 var result = JsonConvert.DeserializeObject>(responseBody); return new CallApiResult { callResult = 1, errorMessage = null, recognResult = result }; } } catch(JsonException ex) { return new CallApiResult { callResult = 0, errorMessage = $"JSON解析失败: {ex.Message}", recognResult = null }; } catch(HttpRequestException ex) { return new CallApiResult { callResult = 0, errorMessage = $"网络异常: {ex.Message}", recognResult = null }; } catch(IOException ex) { return new CallApiResult { callResult = 0, errorMessage = $"读取文件错误: {ex.Message}", recognResult = null }; } catch(Exception ex) { return new CallApiResult { callResult = 0, errorMessage = $"调用失败: {ex.Message}", recognResult = null }; } } //报错图像数据 public static bool SaveBase64ToFile(string base64Data, string filePath) { if (string.IsNullOrWhiteSpace(base64Data)) return false; try { // 处理可能带有 data URI 前缀的 base64 字符串 var commaIndex = base64Data.IndexOf(','); if (commaIndex >= 0) { base64Data = base64Data.Substring(commaIndex + 1); } byte[] fileBytes = Convert.FromBase64String(base64Data); File.WriteAllBytes(filePath, fileBytes); return true; } catch (FormatException) { return false; //MessageBox.Show("Base64 解码失败,数据格式错误。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (IOException ex) { //MessageBox.Show($"写入文件失败: {ex.Message}", "IO 错误", MessageBoxButtons.OK, MessageBoxIcon.Error); Console.WriteLine(ex.Message); return false; } } //--------------------------------------------------------------------- } }