当前位置: 首页 > news >正文

Unity阿里云OpenAPI 获取 Token的C#【记录】

获取Token


using UnityEngine;
using System;
using System.Text;
using System.Linq;
using Newtonsoft.Json.Linq;  
using System.Security.Cryptography;
using UnityEngine.Networking;
using System.Collections.Generic;
using System.Globalization;
using Cysharp.Threading.Tasks;#if UNITY_EDITOR
using UnityEditor;
#endif/// <summary>
/// 获取阿里云的 Token 的代码
/// </summary>
public class AliTTSCtrl : MonoBehaviour
{private readonly string accessKeyId = "********"; private readonly string accessKeySecret = "********"; private readonly string accessKey = "********";private readonly string account = "********";private readonly string regionId = "cn-shanghai";private readonly string version = "2019-02-28";private readonly string action = "CreateToken";private readonly string formatType = "JSON";private readonly string signatureMethod = "HMAC-SHA1";private readonly string signatureVersion = "1.0";private DateTime expirationTime = DateTime.MinValue;void Start(){}// 获取当前有效的 Token[ContextMenu("获取 Token")]
#if UNITY_EDITOR[ExecuteInEditMode]
#endifpublic async UniTask<string> GetToken(){try {var res = CheckTokenExpireTime();if (res.Item1){return res.Item2;}else{//StartCoroutine(RefreshToken());var token = await PostTokenRequest();// 如果正在刷新 Token,可以考虑返回空字符串或者等待刷新完成return token;}}catch(Exception e){Debug.LogError($"错误: {e}");}throw new NullReferenceException("Token 无法获取");}/// <summary>/// 检查Token是否过期或者不存在/// </summary>/// <returns></returns>private (bool, string) CheckTokenExpireTime(){string tokenString = PlayerPrefs.GetString(accessKeyId, "");if (!string.IsNullOrEmpty(tokenString)){JObject token = JObject.Parse(tokenString);long expireTime = token["ExpireTime"].Value<long>();long currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();long timeLeft = expireTime - currentTime;string tokenID = token["Id"].Value<string>();if (timeLeft < 86400) // 24小时 = 86400秒{Debug.Log("Token 将在24小时内过期  True");return (false, null);}else{Debug.Log("Token 还可以使用 False");return (true, tokenID);}}return (false, null);}async UniTask<string> PostTokenRequest(){// 获取当前时间戳string timestamp =   DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture);// 生成随机数string signatureNonce =  Guid.NewGuid().ToString();// 构建请求参数字典 var parameters = new Dictionary<string, string>{{ "AccessKeyId", accessKeyId },{ "Action", action },{ "Format", formatType },{ "RegionId", regionId },{ "SignatureMethod", signatureMethod },{ "SignatureNonce", signatureNonce },{ "SignatureVersion", signatureVersion },{ "Timestamp", timestamp},{ "Version", version }};// 排序并构建规范化的查询字符串string queryString = EncodeDictionary(parameters);//Debug.Log("规范化的请求字符串: " + queryString);string stringToSign = "GET&" + EncodeText("/") + "&" + EncodeText(queryString);//Debug.Log("待签名的字符串: " + stringToSign);string signature = CalculateSignature(accessKeySecret, stringToSign);//Debug.Log("签名: " + signature);signature = EncodeText(signature);//Debug.Log("URL编码后的签名: " + signature);// 构建最终 URLstring url = $"https://nls-meta.cn-shanghai.aliyuncs.com/?Signature={signature}&{queryString}";//Debug.Log("url: " + url);using (UnityWebRequest www = UnityWebRequest.Get(url)){ var asyncOp = www.SendWebRequest();await asyncOp;var header = www.GetResponseHeaders();string headerStr = "";headerStr += www.uri.Host+"\n";//headerStr += www.uri. + "\n";foreach (var head in header){headerStr += $"{head.Key} : {head.Value} \n";}Debug.Log($"请求 Response: {headerStr}");//await www.SendWebRequest();if (www.result != UnityWebRequest.Result.Success){string textData = www.downloadHandler.text;Debug.LogError($"请求错误 Error:{www.result} +  {www.error} -> {textData}");}else{// 解析返回的 JSON 数据string jsonResponse = www.downloadHandler.text;Debug.Log($"请求成功 Response: {jsonResponse}");JObject json = JObject.Parse(jsonResponse);JToken token = json["Token"];if (token != null && token["ExpireTime"] != null && token["Id"] != null){// 缓存 Token 数据PlayerPrefs.SetString(accessKeyId, token.ToString());PlayerPrefs.Save();long expireTime = token["ExpireTime"].Value<long>();long currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();// 将 Unix 时间戳转换为 DateTimeDateTime expiryDateTime = DateTimeOffset.FromUnixTimeSeconds(expireTime).UtcDateTime;DateTime currentDateTime = DateTimeOffset.FromUnixTimeSeconds(currentTime).UtcDateTime;TimeSpan timeLeft = expiryDateTime - currentDateTime;string formattedTime = $"{timeLeft.Days}{timeLeft.Hours}小时 {timeLeft.Minutes}分钟 {timeLeft.Seconds}秒";Debug.Log($"Token 数据保存成功 ; 当前时间:{currentDateTime.ToString("yyyy-MM-dd HH:mm:ss")} - 过期时间:{expiryDateTime.ToString("yyyy-MM-dd HH:mm:ss")} - 有效时长:{formattedTime}");return token.ToString();}else{Debug.Log("Token or required 的字段 不足或者丢失!");}}}return "";}private string EncodeText(string text){string encoded  =  UnityWebRequest.EscapeURL(text).Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~").Replace("%7E", "~");// 将所有小写十六进制代码转换为大写encoded = System.Text.RegularExpressions.Regex.Replace(encoded, "%[0-9a-f]{2}", m => m.Value.ToUpper());return encoded;}private string EncodeDictionary(Dictionary<string, string> dic){var items = dic.OrderBy(kvp => kvp.Key).Select(kvp =>$"{EncodeText(kvp.Key)}={EncodeText(kvp.Value)}");return string.Join("&", items);}private string CalculateSignature(string accessKeySecret, string stringToSign){// 将密钥字符串附加 "&" 后转换为字节var keyBytes = Encoding.UTF8.GetBytes(accessKeySecret + "&");// 将待签名字符串转换为字节var signBytes = Encoding.UTF8.GetBytes(stringToSign);using (var hmacsha1 = new HMACSHA1(keyBytes)){byte[] hashMessage = hmacsha1.ComputeHash(signBytes);string signature = Convert.ToBase64String(hashMessage);//signature = UnityWebRequest.EscapeURL(signature).Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~");return signature;// EncodeToUpper(signature);}}}

使用阿里云 TTS

using System;
using UnityEngine;
//using NativeWebSocket;
using System.Text.RegularExpressions;
using System.Net.Http;
using System.IO;
using UnityEngine.Networking;
using System.Runtime.CompilerServices;
using Cysharp.Threading.Tasks;//using System.Net.WebSockets;//public static class UnityWebRequestExtensions
//{
//    public static TaskAwaiter<AsyncOperation> GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
//    {
//        TaskCompletionSource<AsyncOperation> tcs = new TaskCompletionSource<AsyncOperation>();
//        asyncOp.completed += obj => tcs.SetResult(asyncOp);
//        return tcs.Task.GetAwaiter();
//    }
//}[Serializable]
public class Header
{public string message_id;public string task_id;public string @namespace;public string name;public string appkey;
}public class VoiceSynthesis : MonoBehaviour
{private AliTTSCtrl aliTTSCtrl;private TTSGeneral tTSGeneral;private AudioSource audioSource;void Start(){aliTTSCtrl = GetComponent<AliTTSCtrl>();audioSource = GetComponent<AudioSource>();}// 获取当前有效的 Token[ContextMenu("进行TTS")]
#if UNITY_EDITOR[ExecuteInEditMode]
#endifprivate async UniTask TTS(){if (aliTTSCtrl == null){aliTTSCtrl = GetComponent<AliTTSCtrl>();}if (audioSource == null){audioSource = GetComponent<AudioSource>();}var token = await  aliTTSCtrl.GetToken();Debug.Log($"Token  {token}");if (tTSGeneral == null){tTSGeneral = new TTSGeneral("******", token, audioSource);}await tTSGeneral.SpeakAsync();}void OnDestroy(){}private void OnApplicationQuit(){}
}public class TTSGeneral
{private string appKey = "";  private string accessToken = "";private AudioSource audioSource;private string ttsUrl = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";private string v;private UniTask<string> token;public TTSGeneral(string appKey,string accessToken,AudioSource audioSource){this.appKey = appKey;this.accessToken = accessToken;this.audioSource = audioSource;}public async UniTask<string> SynthesizeSpeech(string text,string format = "wav",int sampleRate = 16000,string voice = "siyue"){try{using (var client = new HttpClient()){var url = $"{ttsUrl}?appkey={appKey}&token={accessToken}&text={Uri.EscapeDataString(text)}&format={format}&sample_rate={sampleRate}&voice={voice}";HttpResponseMessage response = await client.GetAsync(url);response.EnsureSuccessStatusCode();byte[] audioBytes = await response.Content.ReadAsByteArrayAsync();// Save the audio file or play it directly in Unitystring path = Path.Combine(Application.persistentDataPath, "output.wav");File.WriteAllBytes(path, audioBytes);return path;}}catch (Exception ex){Debug.LogError($"Error synthesizing speech: {ex.Message}");throw;}}public async UniTask SpeakAsync(){string textToSpeak = "采用最先进的端到端语音识别框架,字错误率相比上一代系统相对下降10%至30%,并发推理速度相比业内主流推理推理框架提升10倍以上,同时支持实时和离线语音识别,毫秒级延迟。";string audioFilePath = null;try{audioFilePath = await SynthesizeSpeech(textToSpeak);}catch (Exception ex){Debug.LogError($"Error during speech synthesis: {ex.Message}");}//audioFilePath = path.Result;if (!string.IsNullOrEmpty(audioFilePath)){// Load and play the audio file in Unity using UnityWebRequestusing (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + audioFilePath, AudioType.WAV)){DownloadHandlerAudioClip downloadHandler = www.downloadHandler as DownloadHandlerAudioClip;downloadHandler.streamAudio = true; // Stream the audio to save memoryawait www.SendWebRequest();if (www.result == UnityWebRequest.Result.Success){AudioClip clip = downloadHandler.audioClip;if (audioSource != null){audioSource.clip = clip;audioSource.Play();}else{Debug.LogError($"必须有 AudioSource 组件才可以播放");}}else{Debug.LogError($"Failed to load audio file: {www.error}");}}}}
}//public class TTSStream
//{
//    private WebSocket ws;
//    private bool isSynthesisStarted = false;//    async void ConnectWebSocket()
//    {
//        // 替换为你的 WebSocket 服务地址和 Token
//        ws = new WebSocket("wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1?token=your-nls-token");
//        ws.OnOpen += () =>
//        {
//            Debug.Log("WebSocket connected!");
//            SendStartSynthesis();
//        };//        ws.OnError += (e) =>
//        {
//            Debug.LogError("Error: " + e);
//        };
//        ws.OnClose += (e) =>
//        {
//            Debug.Log("WebSocket closed!");
//        };//        ws.OnMessage += (bytes) =>
//        {
//            Debug.Log("Received message: " + bytes);
//        };//         Keep sending messages at every 0.3s
//        //InvokeRepeating("SendWebSocketMessage", 0.0f, 0.3f);//        await ws.Connect();
//    }//    void Update()
//    {
//#if !UNITY_WEBGL || UNITY_EDITOR
//        if (ws != null)
//        {
//            ws.DispatchMessageQueue();//        }//#endif
//    }//    async void SendWebSocketMessage()
//    {
//        if (ws.State == WebSocketState.Open)
//        {
//            // Sending bytes
//            await ws.Send(new byte[] { 10, 20, 30 });//            // Sending plain text
//            await ws.SendText("plain text message");
//        }
//    }//    private async void SendStartSynthesis()
//    {
//        var header = GetHeader("StartSynthesis");
//        var paramsJson = JsonUtility.ToJson(header);
//        await ws.SendText(paramsJson);
//    }//    string GenerateUUID()
//    {
//        long d = DateTime.Now.Ticks;
//        long d2 = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds * 1000;
//        return Regex.Replace("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "[xy]", delegate (Match match)
//        {
//            int r = new System.Random().Next(16);
//            if (d > 0)
//            {
//                r = ((int)(d + r) % 16) | 0;
//                d = (long)Math.Floor(d / 16.0);
//            }
//            else
//            {
//                r = ((int)(d2 + r) % 16) | 0;
//                d2 = (long)Math.Floor(d2 / 16.0);
//            }
//            return (match.Value == "x" ? r : (r & 0x3 | 0x8)).ToString("x");
//        });
//    }//    Header GetHeader(string name)
//    {
//        return new Header
//        {
//            message_id = GenerateUUID(),
//            task_id = GenerateUUID(), // 根据需要生成 task_id
//            @namespace = "FlowingSpeechSynthesizer",
//            name = name,
//            appkey = "your-nls-appkey"
//        };
//    }//    public async void CloseWs()
//    {
//        if (ws != null)
//        {
//            await ws.Close();
//            ws = null;
//        }
//    }//}

使用阿里云 OCR

using System;
using System.Collections;
using System.Collections.Generic;using UnityEngine;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Imagine.WebAR;
using Cysharp.Threading.Tasks;
using Tea;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Ocr_api20210707.Models;
using AlibabaCloud.TeaUtil.Models;
using AlibabaCloud.SDK.Ocr_api20210707;
using AlibabaCloud.TeaUtil;
using AlibabaCloud.OpenApiClient;
using AlibabaCloud.OpenApiUtil;
using System.Reflection;public class AliOCR : MonoBehaviour
{public Texture2D texture;public RenderTexture textureRender;private OCRUnified oCR;private TextureExtractor_WarpedImage warpedImage;private readonly string accessKeyId = "********"; private readonly string accessKeySecret = "********";  // Start is called before the first frame updatevoid Start(){if (oCR == null){oCR = new OCRUnified(accessKeyId, accessKeySecret);}warpedImage = GetComponent<TextureExtractor_WarpedImage>();}public void OnImageFound(string id){if (warpedImage == null){warpedImage = GetComponent<TextureExtractor_WarpedImage>();}warpedImage.ExtractTexture(id);//string ocrContent  = await OCR();Debug.Log($"执行 OCR  识别.....");try{OCR(); // 启动但不等待}catch (Exception ex){Debug.LogError("OCR failed 2 : " + ex.Message);}}public void OnImageLost(string id){}// 获取当前有效的 Token[ContextMenu("进行ORC")]
#if UNITY_EDITOR[ExecuteInEditMode]
#endifprivate void OCR(){Debug.Log($"执行 OCR  识别2 .....");if (oCR == null){oCR = new OCRUnified(accessKeyId, accessKeySecret);}try{//byte[] imageData = texture.EncodeToJPG();var imaStream = RenderTextureAsync();string res = oCR.Run(imaStream);//string res = await UniTask.Create(async () =>//{//    // 直接调用同步方法//    string result = oCR.Run(imaStream);//    await UniTask.Yield(); // 等待至少下一帧//    return result;//});if (res == ""){Debug.Log($"没有识别到任何文字:{res}");}else{Debug.Log($"识别到文字:{res}");}imaStream.Close();//return  res;}catch (Exception ex){Debug.LogError("OCR failed2 : " + ex.Message);//return "OCR failed";  // 返回错误信息}}private Stream RenderTextureAsync(){// 等待渲染线程结束//await UniTask.WaitForEndOfFrame(this);// 临时激活渲染纹理的上下文RenderTexture.active = textureRender;// 创建一个新的 Texture2D 对象来接收像素Texture2D texture2D = new Texture2D(textureRender.width, textureRender.height, TextureFormat.RGB24, false);texture2D.ReadPixels(new Rect(0, 0, textureRender.width, textureRender.height), 0, 0);texture2D.Apply();// 重置渲染纹理的上下文RenderTexture.active = null;// 编码 Texture2D 数据为 JPGbyte[] jpgData = texture2D.EncodeToJPG();// 释放 Texture2D 对象
#if UNITY_EDITORDestroyImmediate(texture2D);
#elseDestroy(texture2D);
#endif// 将 JPG 数据写入内存流//using (MemoryStream stream = new MemoryStream())//{//    stream.Write(jpgData, 0, jpgData.Length);//    return stream;//    // 这里可以添加额外的处理,如保存文件或发送数据//}return new MemoryStream(jpgData);}}/// <summary>
/// OCR 统一识别
/// </summary>
public class OCRUnified
{private AlibabaCloud.OpenApiClient.Client aliClient;private AlibabaCloud.SDK.Ocr_api20210707.Client aliClient2;public OCRUnified(string accessKeyId, string accessKeySecret){aliClient = CreateClient(accessKeyId, accessKeySecret);aliClient2 = CreateClient2(accessKeyId, accessKeySecret);}public string Run(Stream textureBody){try{Debug.Log($"执行 OCR  识别3 .....");AlibabaCloud.OpenApiClient.Models.Params params_ = CreateApiInfo();Debug.Log($" 1 OCR  创建 API 成功 .....");// query paramsDictionary<string, object> queries = new Dictionary<string, object>() { };queries["Type"] = "Advanced";queries["OutputFigure"] = true;//byte[] imageData = texture.EncodeToJPG();// 需要安装额外的依赖库,直接点击下载完整工程即可看到所有依赖。//Stream body = new MemoryStream(imageData) ;//AlibabaCloud.DarabonbaStream.StreamUtil.ReadFromFilePath("<your-file-path>");// runtime optionsAlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();Debug.Log($" 2 OCR  创建 RuntimeOptions 成功 .....");AlibabaCloud.OpenApiClient.Models.OpenApiRequest request = new AlibabaCloud.OpenApiClient.Models.OpenApiRequest{Query = AlibabaCloud.OpenApiUtil.Client.Query(queries),Stream = textureBody,};Debug.Log($" 3 OCR  创建 OpenApiRequest 成功 .....");// 复制代码运行请自行打印 API 的返回值// 返回值实际为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode。//Debug.Log($"执行 OCR  params_:{params_.ToString()} - request:{request} - runtime:{runtime}");Dictionary<string, object> res = null;try{Debug.Log($"params : {ConvertToJson(params_)}");Debug.Log($"request : {ConvertToJson(request)}");Debug.Log($"runtime : {ConvertToJson(runtime)}");res = aliClient.CallApi(params_, request, runtime); //new Dictionary<string, object>();}catch (Exception ex){Debug.LogError($"CallApi 错误 {ex}");}Debug.Log($" 4 OCR  请求 成功 .....");string jsonString = JsonConvert.SerializeObject(res, Formatting.Indented);if (res.ContainsKey("statusCode")){var statusCode = res["statusCode"];int code = int.Parse(statusCode.ToString());if (code == 200){// 打印 JSON 字符串到控制台Debug.Log(jsonString);// 将 JSON 字符串解析为 JObjectJObject jsonObject = JObject.Parse(jsonString);// 从 JObject 获取 "Data" 下的 "Content"string content = jsonObject["body"]["Data"]["Content"].ToString();Debug.Log($"content = {content}");return content;//PrintDictionary(res);}else{var strRes = $"识别异常 {code} -> {jsonString} ";Debug.LogError(strRes);return strRes;}}return $"不是有效的返回 {jsonString}";}catch (Exception ex){var strRes = $"ORC 错误: {ex}";Debug.LogError(strRes);return strRes;}}public static string ConvertToJson(object obj){var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);var result = new System.Text.StringBuilder();result.Append("{");bool first = true;foreach (var property in properties){if (!first){result.Append(", ");}else{first = false;}try{var value = property.GetValue(obj, null);string jsonValue = value != null ? value.ToString() : "null";result.AppendFormat("\"{0}\": {1}", property.Name, jsonValue);}catch (Exception ex){// Handle the exception if the property cannot be serialized to JSONresult.AppendFormat("\"{0}\": \"Error: {1}\"", property.Name, ex.Message);}}result.Append("}");return result.ToString();}public static void PrintJson(object obj){Debug.Log(ConvertToJson(obj));}// 打印字典的方法//void PrintDictionary(Dictionary<string, object> dictionary)//{//    foreach (KeyValuePair<string, object> entry in dictionary)//    {//        // 检查值的类型,如果是列表或数组,需要特别处理//        if (entry.Value is List<string>)//        {//            List<string> list = entry.Value as List<string>;//            Debug.Log(entry.Key + ": [" + string.Join(", ", list) + "]");//        }//        else//        {//            Debug.Log(entry.Key + ": " + entry.Value);//        }//    }//}/// <term><b>Description:</b></term>/// <description>/// <para>使用AK&amp;SK初始化账号Client</para>public AlibabaCloud.OpenApiClient.Client CreateClient(string accessKeyId, string accessKeySecret){// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378671.html。AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config{// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。AccessKeyId = accessKeyId,// Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。AccessKeySecret = accessKeySecret //Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),};// Endpoint 请参考 https://api.aliyun.com/product/ocr-apiconfig.Endpoint = "ocr-api.cn-hangzhou.aliyuncs.com";return new AlibabaCloud.OpenApiClient.Client(config);}public AlibabaCloud.SDK.Ocr_api20210707.Client CreateClient2(string accessKeyId, string accessKeySecret){// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378671.html。AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config{// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。AccessKeyId = accessKeyId,//Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。AccessKeySecret = accessKeySecret,// Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),};// Endpoint 请参考 https://api.aliyun.com/product/ocr-apiconfig.Endpoint = "ocr-api.cn-hangzhou.aliyuncs.com";return new AlibabaCloud.SDK.Ocr_api20210707.Client(config);}public string Run2(Stream textureBody){//AlibabaCloud.SDK.Ocr_api20210707.Client client = CreateClient();// 需要安装额外的依赖库,直接点击下载完整工程即可看到所有依赖。Stream bodyStream = AlibabaCloud.DarabonbaStream.StreamUtil.ReadFromFilePath("<your-file-path>");var dd = new AlibabaCloud.SDK.Ocr_api20210707.Models.DataSubImagesFigureInfoValue();AlibabaCloud.SDK.Ocr_api20210707.Models.RecognizeAllTextRequest recognizeAllTextRequest = new AlibabaCloud.SDK.Ocr_api20210707.Models.RecognizeAllTextRequest{Type = "Advanced",OutputFigure = true,Body = textureBody,};AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();try{// 复制代码运行请自行打印 API 的返回值recognizeAllTextRequest.Validate();Debug.Log($" 验证通过 ");var res = aliClient2.RecognizeAllTextWithOptions(recognizeAllTextRequest, runtime);return res.Body.Data.Content;}catch (TeaException error){// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。// 错误 messageDebug.Log($"Tea错误 : {error.Message}");// 诊断地址Debug.Log($"Tea错误2 : {error.Data["Recommend"]}");AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);}catch (Exception _error){Debug.Log($"错误 : {_error}");TeaException error = new TeaException(new Dictionary<string, object>{{ "message", _error.Message }});// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。// 错误 messageDebug.Log($"错误2 : {error.Message}");// 诊断地址Debug.Log($"错误3 : {error.Data["Recommend"]}");AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);}return "";}/// <term><b>Description:</b></term>/// <description>/// <para>API 相关</para>public AlibabaCloud.OpenApiClient.Models.Params CreateApiInfo(){AlibabaCloud.OpenApiClient.Models.Params params_ = new AlibabaCloud.OpenApiClient.Models.Params{// 接口名称Action = "RecognizeAllText",// 接口版本Version = "2021-07-07",// 接口协议Protocol = "HTTPS",// 接口 HTTP 方法Method = "POST",AuthType = "AK",Style = "V3",// 接口 PATHPathname = "/",// 接口请求体内容格式ReqBodyType = "json",// 接口响应体内容格式BodyType = "json",};return params_;}public void RecognizeAllTextWithOptions(){}}

相关文章:

Unity阿里云OpenAPI 获取 Token的C#【记录】

获取Token using UnityEngine; using System; using System.Text; using System.Linq; using Newtonsoft.Json.Linq; using System.Security.Cryptography; using UnityEngine.Networking; using System.Collections.Generic; using System.Globalization; using Cysharp.Thr…...

java+vue项目部署记录

目录 前言 一、java和vue 二、部署记录 1.获取代码 2.运行前端 3.运行后端 三、其他 1.nvm 总结 前言 近期工作需要部署一套javavue前后分离的项目&#xff0c;之前都略有接触&#xff0c;但属于不及皮毛的程度&#xff0c;好在对其他开发语言、html js这些还算熟&am…...

PID 控制算法(二):C 语言实现与应用

在本文中&#xff0c;我们将用 C 语言实现一个简单的 PID 控制器&#xff0c;并通过一个示例来演示如何使用 PID 控制算法来调整系统的状态&#xff08;如温度、速度等&#xff09;。同时&#xff0c;我们也会解释每个控制参数如何影响系统的表现。 什么是 PID 控制器&#xf…...

深入MapReduce——计算模型设计

引入 通过引入篇&#xff0c;我们可以总结&#xff0c;MapReduce针对海量数据计算核心痛点的解法如下&#xff1a; 统一编程模型&#xff0c;降低用户使用门槛分而治之&#xff0c;利用了并行处理提高计算效率移动计算&#xff0c;减少硬件瓶颈的限制 优秀的设计&#xff0c…...

在Spring Boot中使用SeeEmitter类实现EventStream流式编程将实时事件推送至客户端

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…...

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践&#xff1a;一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏&#xff0c;觉得这个抽屉式的侧滑栏非常的有趣&#xff0c;打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 &#xff08;C&#xff0c;GIF帧率砍到毛都不剩了&#xff09; QProperty…...

基于ESP32-IDF驱动GPIO输出控制LED

基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…...

OpenCV文字绘制支持中文显示

OpenCV版本&#xff1a;4.4 IDE&#xff1a;VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示&#xff0c;网上很多方法推荐的都是使用FreeType来支持&#xff0c;FreeType是什么呢&#xff1f;FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…...

jenkins-k8s pod方式动态生成slave节点

一. 简述&#xff1a; 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式&#xff0c;Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务&#xff0c;从而充分利用集群资源并实现更好的隔离性…...

消息队列篇--基础篇(消息队列特点,应用场景、点对点和发布订阅工作模式,RabbmitMQ和Kafka代码示例等)

1、消息队列的介绍 消息&#xff08;Message&#xff09;是指在应用之间传送的数据&#xff0c;消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09…...

Jetpack架构组件学习——使用Glance实现桌面小组件

基本使用 1.添加依赖 添加Glance依赖: // For AppWidgets supportimplementation "androidx.glance:glance-appwidget:1.1.0"// For interop APIs with Material 3implementation "androidx.glance:glance-material3:1.1.0"// For interop APIs with Mater…...

go读取excel游戏配置

1.背景 游戏服务器&#xff0c;配置数据一般采用csv/excel来作为载体&#xff0c;这种方式&#xff0c;策划同学配置方便&#xff0c;服务器解析也方便。在jforgame框架里&#xff0c;我们使用以下的excel配置格式。 然后可以非常方便的进行数据检索&#xff0c;例如&#xff…...

Linux系统下速通stm32的clion开发环境配置

陆陆续续搞这个已经很久了。 因为自己新电脑是linux系统无法使用keil&#xff0c;一开始想使用vscode里的eide但感觉不太好用&#xff1b;后面想直接使用cudeide但又不想妥协&#xff0c;想趁着这个机会把linux上的其他单片机开发配置也搞明白&#xff1b;而且非常想搞懂cmake…...

快慢指针及原理证明(swift实现)

目录 链表快慢指针一、快慢指针基本介绍二、快慢指针之找特殊节点1.删除链表的倒数第k个结点题目描述解题思路 2.链表的中间节点题目描述解题思路 三、快慢指针之环形问题1.判断环形链表题目描述解题思路 2.判断环形链表并返回入环节点题目描述解题思路 3.变种——判断快乐数题…...

web前端3--css

注意&#xff08;本文一切代码一律是在vscode中书写&#xff09; 1、书写位置 1、行内样式 //<标签名 style"样式声明"> <p style"color: red;">666</p> 2、内嵌样式 1、style标签 里面写css代码 css与html之间分离 2、css属性:值…...

一文大白话讲清楚webpack基本使用——5——babel的配置和使用

文章目录 一文大白话讲清楚webpack基本使用——5——babel的配置和使用1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. babel-loader的配置和使用2.1 针对ES6的babel-loader2.2 针对typescript的babel-loader2.3 babel配置文件 一文大白话讲清楚webpack基…...

Python自动化运维:一键掌控服务器的高效之道

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...

基于quartz,刷新定时器的cron表达式

文章目录 前言基于quartz&#xff0c;刷新定时器的cron表达式1. 先看一下测试效果2. 实现代码 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&…...

HTML常用属性

HTML标签的常见属性包括许多不同的功能&#xff0c;可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释&#xff1a; 1. src 描述&#xff1a;src&#xff08;source&#xff09;属性指定一个资源的路径&#xff0c;通常用于图像、音频、视频等标签。常见…...

在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具

在 3D 应用程序中&#xff0c;交互式操作对象&#xff08;如平移、旋转、缩放&#xff09;是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo&#xff0c;用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo&#xff0c;并展示如何通过代码实…...

蓝桥杯练习日常|递归-进制转换

蓝桥云课760数的计算 一、递归 题目&#xff1a; 我的解题代码&#xff1a; #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…...

LabVIEW滤波器选择与参数设置

在信号处理应用中&#xff0c;滤波器是去除噪声、提取目标信号的重要工具。LabVIEW 提供多种类型的滤波器&#xff08;如低通、高通、带通、带阻&#xff09;&#xff0c;用户需要根据采样频率、信号特性和应用需求合理选择滤波器类型及参数设置。本文以 采样率 100kHz&#xf…...

【c语言日寄】Vs调试——新手向

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…...

C#中的Timers.Timer使用用法及常见报错

System.Timers.Timer 是一个基于服务器的计时器&#xff0c;它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境&#xff0c;并且不应该与用户界面(UI)直接交互。在 ASP.NET 中&#xff0c;通常使用 System.Timers.Timer 来处理周期性的任务。 主要使用步骤&am…...

chrome小插件:长图片等分切割

前置条件&#xff1a; 安装有chrome谷歌浏览器的电脑 使用步骤&#xff1a; 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.选择图片进行切割&#xff0c;切割完成后会自动保存 代码…...

mysql数据被误删的恢复方案

文章目录 一、使用备份恢复二、使用二进制日志&#xff08;Binary Log&#xff09;三、使用InnoDB表空间恢复四、使用第三方工具预防措施 数据误删是一个严重的数据库管理问题&#xff0c;但通过合理的备份策略和使用适当的恢复工具&#xff0c;可以有效地减少数据丢失的风险…...

K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略

1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...

Unity Line Renderer Component入门

Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组&#xff0c;并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性&#xff1a;Line Renderer 绘制的线条…...

计算机工程:解锁未来科技之门!

计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展&#xff0c;计算机技术已经深深渗透到我们生活的方方面面&#xff0c;从医疗、金融到教育&#xff0c;无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业&#xff0c;计算机技术的应用尤为突出。比如&a…...

翻译:How do I reset my FPGA?

文章目录 背景翻译&#xff1a;How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放&#xff08;同步复…...

在Unity中使用大模型进行离线语音识别

文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…...

SpringBoot+Vue使用Echarts

前言 在vue项目中使用echarts&#xff0c;本次演示是使用vue2 1 前端准备 echarts官网&#xff1a; https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败&#xff0c;…...

【QT】-explicit关键字

explicit explicit 是一个 C 关键字&#xff0c;用于修饰构造函数。它的作用是防止构造函数进行隐式转换。 为什么需要 explicit&#xff1f; 在没有 explicit 的情况下&#xff0c;构造函数可以用于隐式类型转换。这意味着&#xff0c;如果你有一个接受某种类型的参数的构造…...

docker: Device or resource busy

(base) [rootbddx-vr-gpu-bcc2 /]#rm -rf /ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/ rm: cannot remove ‘/ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/merged’: Device or re…...

Vue - toRefs() 和 toRef() 的使用

一、toRefs() 在 Vue 3 中,toRefs()可以将响应式对象的属性转换为可响应的 refs。主要用于在解构响应式对象时&#xff0c;保持属性的响应性。 1. 导入 toRefs 函数 import { toRefs } from vue;2. 将响应式对象的属性转换为 ref const state reactive({count: 0,message:…...

(2024,MLLM,Healthcare,综述)多模态学习是否已在医疗保健领域实现通用智能?

Has Multimodal Learning Delivered Universal Intelligence in Healthcare? A Comprehensive Survey 目录 0. 摘要 1. 简介 5. MLLM 5.1 模态编码器与跨模态适配器 5.1.1 图像编码器 (Image Encoder) 5.1.2 语言模型 (Language Model) 5.1.3 跨模态适配器 (Cross-moda…...

css命名规范——BEM

目录 引言 BEM是什么? 块Block 元素Element 修饰语Modifier BEM解决了哪些问题? 在流行框架的组件中使用 BEM 格式 实战 认识设计图 如何使用当前的css规范正确命名? 引言 css样式类命名难、太难了,难于上青天,这个和js变量命名还不一样。看看项目中五花八门的样…...

使用PHP函数 “is_object“ 检查变量是否为对象类型

在PHP中&#xff0c;变量可以保存不同类型的值&#xff0c;包括整数、字符串、数组、布尔值等等。其中&#xff0c;对象是一种特殊的数据类型&#xff0c;用于封装数据和方法。在处理PHP代码中&#xff0c;我们经常需要检查一个变量是否为对象类型&#xff0c;以便进行相应的处…...

Golang:使用DuckDB查询Parquet文件数据

本文介绍DuckDB查询Parquet文件的典型应用场景&#xff0c;掌握DuckDB会让你的产品分析能力更强&#xff0c;相反系统运营成本相对较低。为了示例完整&#xff0c;我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…...

Moretl FileSync增量文件采集工具

永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…...

消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)

Apache Pulusar是一个分布式、多租户、高性能的发布/订阅&#xff08;Pub/Sub&#xff09;消息系统&#xff0c;最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点&#xff0c;提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力&#xff0c;适用于大规模分布式系…...

linux 扩容

tmpfs tmpfs 82M 0 82M 0% /run/user/1002 tmpfs tmpfs 82M 0 82M 0% /run/user/0 [输入命令]# fdisk -lu Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors Units: sectors of 1 * 512 512 bytes Sector size (logi…...

数据表中的数据查询

文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…...

深入了解 Java split() 方法:分割字符串的利器

Java 提供的 split() 方法是 String 类中一个常用的工具&#xff0c;它可以将一个字符串根据指定的分隔符切割成多个子字符串&#xff0c;并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式&#xff0c;并…...

Ubuntu 安装 docker 配置环境及其常用命令

Docker 安装与配置指南 本文介绍如何在 Ubuntu 系统上安装 Docker&#xff0c;解决权限问题&#xff0c;配置 Docker Compose&#xff0c;代理端口转发&#xff0c;容器内部代理问题等并进行相关的优化设置。参考官方文档&#xff1a;Docker 官方安装指南 一、安装 Docker 1…...

Android Studio安装配置

一、注意事项 想做安卓app和开发板通信&#xff0c;踩了大坑&#xff0c;Android 开发不是下载了就能直接开发的&#xff0c;对于新手需要注意的如下&#xff1a; 1、Android Studio版本&#xff0c;根据自己的Android Studio版本对应决定了你所兼容的AGP&#xff08;Android…...

leetcode 面试经典 150 题:有效的括号

链接有效的括号题序号20题型字符串解法栈难度简单熟练度✅✅✅ 题目 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须…...

C语言 指针_野指针 指针运算

野指针&#xff1a; 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09; 指针非法访问&#xff1a; int main() {int* p;//p没有初始化&#xff0c;就意味着没有明确的指向//一个局部变量不初始化&#xff0c;放…...

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局

目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...

java基础学习——jdbc基础知识详细介绍

引言 数据的存储 我们在开发 java 程序时&#xff0c;数据都是存储在内存中的&#xff0c;属于临时存储&#xff0c;当程序停止或重启时&#xff0c;内存中的数据就会丢失&#xff0c;我们为了解决数据的长期存储问题&#xff0c;有以下解决方案&#xff1a; 通过 IO流书记&…...