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

Unity接入火山引擎/豆包大模型文生图,实现AI绘画

1.访问火山引擎

2.注册后实名信息

3.产品—火山方舟—视觉大模型。找到对应模型,开通或者免费领取体验资源

4.点击查看详情—立即使用,按步骤获取产品密钥

5.打开unity 新建脚本(以下为主要方法,构建请求体后创建签名及认证)

 IEnumerator GenerateImage(){long timestamp = GetTimestamp();string method = "POST"; // 请求方法,固定为POST,可根据实际情况调整string path = ""; // 这里假设你的请求路径是/generate,需根据实际API调整string contentType = "application/json"; // 根据请求体内容类型设置// 构建请求的JSON格式数据,按照文档里请求格式要求填充各参数ImageGenerationRequest requestData = new ImageGenerationRequest{req_key = "high_aes_general_v20_L",prompt = InputField.text,model_version = "general_v2.0_L",req_schedule_conf = "general_v20_9B_rephraser",seed = -1,scale = 3.5f,ddim_steps = 16,width = 512,height = 512,use_sr = true,return_url = false,logo_info = new LogoInfo{add_logo = false,position = 0,language = 0,opacity = 0.3f,logo_text_content = "这里是明水印内容"}};string requestBody = JsonUtility.ToJson(requestData);// 生成签名string signature = GenerateSignature(timestamp, accessKey, secretKey, method, path, contentType, requestBody);//string signature = "1caf8e82d88a9fc8f094f6d800616522e7c78f23f7e4ee568625b9b825e15eb0";//Debug.Log(signature);UnityWebRequest request = new UnityWebRequest(apiUrl, method);byte[] bodyRaw = Encoding.UTF8.GetBytes(requestBody);request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();// 设置Content-Type请求头request.SetRequestHeader("Content-Type", contentType);//设置Host请求头,从API请求地址中提取主机部分//string host = new Uri(apiUrl).Host;// request.SetRequestHeader("host", host);// 设置X-Date请求头,使用获取到的时间戳转换后的格式string xDate = GetFormattedXDate(timestamp);request.SetRequestHeader("X-Date", xDate);// 计算并设置X-Content-Sha256请求头,对请求体内容计算SHA256哈希值string xContentSha256 = HashSHA256(bodyRaw);request.SetRequestHeader("X-Content-Sha256", xContentSha256);Debug.Log(xContentSha256);// 构建并设置Authorization请求头,包含签名等认证信息string credentialScope = $"{xDate.Substring(0, 8)}/{region}/{service}/request";string authorizationHeader = $"HMAC-SHA256 Credential={accessKey}/{credentialScope}, SignedHeaders=host;x-content-sha256;x-date, Signature={signature}";request.SetRequestHeader("Authorization", authorizationHeader);yield return request.SendWebRequest();// 按照新的方式判断请求结果,使用isDone和isNetworkError、isHttpError属性来替代原来的.result属性判断if (request.isDone){// 解析返回的JSON数据,获取图片相关内容并处理显示(按文档返回格式要求操作)string responseJson = request.downloadHandler.text;Debug.Log(responseJson);ImageGenerationResponse response = JsonUtility.FromJson<ImageGenerationResponse>(responseJson);if (response.data.binary_data_base64 != null && response.data.binary_data_base64.Count > 0){byte[] imageBytes = System.Convert.FromBase64String(response.data.binary_data_base64[0]);Texture2D texture = new Texture2D(2, 2);texture.LoadImage(imageBytes);Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));resultImage.sprite = sprite;}else{Debug.LogError("没有获取到有效的图片数据");}}else{Debug.LogError("请求出错: " + request.error);}}

6.效果

贴个源代码,就一个脚本,换成你自己申请的sk,ak即可

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Text;
using UnityEngine.UI;
using System.Collections.Generic;
using System;
using System.Security.Cryptography;
using System.Linq;// 定义请求参数对应的结构体,按照文档里请求格式要求来组织数据
[System.Serializable]
public struct ImageGenerationRequest
{public string req_key;public string prompt;public string model_version;public string req_schedule_conf;public int seed;public float scale;public int ddim_steps;public int width;public int height;public bool use_sr;public bool return_url;public LogoInfo logo_info;
}// 定义请求里logo相关信息的结构体
[System.Serializable]
public struct LogoInfo
{public bool add_logo;public int position;public int language;public float opacity;public string logo_text_content;
}// 定义返回数据对应的结构体,按照文档里返回格式要求来解析响应内容
[System.Serializable]
public struct ImageGenerationResponse
{public int code;public ResponseData data;public string message;public string request_id;public int status;public string time_elapsed;
}[System.Serializable]
public struct ResponseData
{public AlgorithmBaseResp algorithm_base_resp;public List<string> binary_data_base64;public string pe_result;public string predict_tags_result;public string rephraser_result;public string request_id;
}[System.Serializable]
public struct AlgorithmBaseResp
{public int status_code;public string status_message;
}public class TextToImage : MonoBehaviour
{// 火山引擎文生图服务的API请求地址,替换为你申请到的真实地址public string apiUrl = "https://your-volcengine-api-url.com/generate";// 你的火山引擎应用的访问密钥,根据实际申请填写public string accessKey = "your-access-key";// 你的火山引擎应用的秘密密钥,根据实际申请填写public string secretKey = "your-secret-key";// 用于输入文生图的文本提示,比如描述画面内容等public string textPrompt = "美丽的自然风光";// 用于展示生成图片的Unity UI的Image组件,在场景中挂载并赋值到此处public Image resultImage;// 火山引擎服务对应的区域,需替换为实际使用的区域名称private string region = "cn-north-1";// 火山引擎服务对应的服务名称,需替换为实际的服务名称(比如文生图相关服务的名称)private string service = "cv";// 获取时间戳,用于请求签名等操作(按常见的时间戳生成方式示例)private long GetTimestamp(){System.DateTime startTime = System.DateTime.Now.ToUniversalTime();return (long)(startTime - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;}// 生成签名,按照火山引擎要求完善后的签名算法private string GenerateSignature(long timestamp, string accessKey, string secretKey, string method, string path, string contentType, string requestBody){// 假设这里有对应的区域和服务名称变量,需要根据实际情况正确赋值// 第一步:获取格式化后的X-Date,格式为YYYYMMDD'T'HHmmss'Z',用于后续多处时间相关的标识string xDate = GetFormattedXDate(timestamp);// 第二步:构建规范请求字符串(CanonicalRequest)StringBuilder canonicalRequestBuilder = new StringBuilder();// 1. 添加请求方法(HTTPRequestMethod),按照文档要求转换为大写canonicalRequestBuilder.Append(method.ToUpper()).Append("\n");// 2. 添加规范化URI(CanonicalURI)// 根据文档,如果URI为空,使用"/"作为绝对路径;若不为空,需按照RFC3986规范进行编码string canonicalURI;if (string.IsNullOrEmpty(path)){canonicalURI = "/";}else{canonicalURI = System.Web.HttpUtility.UrlEncode(path, System.Text.Encoding.UTF8);}canonicalRequestBuilder.Append(canonicalURI).Append("\n");canonicalRequestBuilder.Append("Action=CVProcess&Version=2022-08-31").Append("\n");// 4. 添加规范化请求头(CanonicalHeaders)// 遍历要参与签名的请求头,将请求头名称转换为小写,去除值的前后空格,然后按照“名称:值\n”的格式添加到构建器中// 注意最后要额外添加一个换行符,确保格式符合文档要求,且host和x-date如果存在于请求头中则必选参与签名计算StringBuilder canonicalHeadersBuilder = new StringBuilder();AddCanonicalHeader(canonicalHeadersBuilder, "host", new Uri(apiUrl).Host);AddCanonicalHeader(canonicalHeadersBuilder, "x-content-sha256", HashSHA256(Encoding.UTF8.GetBytes(requestBody)));AddCanonicalHeader(canonicalHeadersBuilder, "x-date", xDate);// AddCanonicalHeader(canonicalHeadersBuilder, "content-type", contentType);string canonicalHeaders = canonicalHeadersBuilder.ToString() + "\n";canonicalRequestBuilder.Append(canonicalHeaders);// 5. 添加参与签名的请求头列表(SignedHeaders)// 将参与签名的请求头名称转换为小写并用“;”连接,确保顺序正确且包含host和x-date(如果存在),用于后续签名计算中明确参与的请求头string signedHeaders = "host;x-content-sha256;x-date";canonicalRequestBuilder.Append(signedHeaders).Append("\n");// 6. 添加请求体哈希值(HexEncode(Hash(RequestPayload)))// 计算请求体的哈希值(使用SHA256算法),并将结果转换为十六进制编码后添加到规范请求字符串中canonicalRequestBuilder.Append(HashSHA256(Encoding.UTF8.GetBytes(requestBody)));string canonicalRequest = canonicalRequestBuilder.ToString();Debug.Log(canonicalRequest);// 第三步:计算规范请求的哈希值(HexEncode(Hash(CanonicalRequest)))string hashedCanonicalRequest = HashSHA256(Encoding.UTF8.GetBytes(canonicalRequest));// 第四步:构建凭证范围字符串(CredentialScope)// 按照文档要求,取X-Date中的日期部分(前8位),与region、service和固定的“request”字符串拼接,用于界定签名的有效范围string shortDate = xDate.Substring(0, 8);string credentialScope = $"{shortDate}/{region}/{service}/request";// 第五步:构建待签名字符串(StringToSign)string stringToSign = $"HMAC-SHA256\n{xDate}\n{credentialScope}\n{hashedCanonicalRequest}";Debug.Log(stringToSign);// 第六步:计算签名密钥(kSigning)// 通过多层HMAC计算,使用秘密密钥(secretKey)和相关的日期、区域、服务信息逐步派生得到签名密钥byte[] secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);byte[] kDate = HmacSha256(secretKeyBytes, shortDate);byte[] kRegion = HmacSha256(kDate, region);byte[] kService = HmacSha256(kRegion, service);byte[] kSigning = HmacSha256(kService, "request");// 第七步:计算签名(Signature)// 使用派生得到的签名密钥(kSigning)和待签名字符串(StringToSign)进行HMAC计算,然后将结果转换为十六进制编码byte[] signatureBytes = HmacSha256(kSigning, stringToSign);string signature = ByteArrayToHexString(signatureBytes);return signature;}// 辅助方法,用于添加规范化的请求头到构建器中private void AddCanonicalHeader(StringBuilder builder, string headerName, string headerValue){builder.Append(headerName.ToLower()).Append(":").Append(headerValue.Trim()).Append("\n");}// 辅助方法,执行HMAC-SHA256计算,返回字节数组结果private byte[] HmacSha256(byte[] key, string data){using (HMACSHA256 hmac = new HMACSHA256(key)){return hmac.ComputeHash(Encoding.UTF8.GetBytes(data));}}// 辅助方法,将字节数组转换为十六进制编码的字符串private string ByteArrayToHexString(byte[] bytes){StringBuilder hex = new StringBuilder(bytes.Length * 2);foreach (byte b in bytes){hex.AppendFormat("{0:x2}", b);}return hex.ToString();}// 辅助方法,用于将时间戳转换为符合要求的X-Date格式字符串private string GetFormattedXDate(long timestamp){DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(timestamp).ToUniversalTime();return dateTimeOffset.ToString("yyyyMMdd'T'HHmmss'Z'");}// 计算字节数组的SHA256哈希值,并返回十六进制字符串表示private string HashSHA256(byte[] content){using (SHA256 sha256Hash = SHA256.Create()){byte[] hashBytes = sha256Hash.ComputeHash(content);StringBuilder sb = new StringBuilder();for (int i = 0, n = hashBytes.Length; i < n; i++){sb.Append(hashBytes[i].ToString("x2"));}return sb.ToString();}}IEnumerator GenerateImage(){long timestamp = GetTimestamp();string method = "POST"; // 请求方法,固定为POST,可根据实际情况调整string path = ""; // 这里假设你的请求路径是/generate,需根据实际API调整string contentType = "application/json"; // 根据请求体内容类型设置// 构建请求的JSON格式数据,按照文档里请求格式要求填充各参数ImageGenerationRequest requestData = new ImageGenerationRequest{req_key = "high_aes_general_v20_L",prompt = textPrompt,model_version = "general_v2.0_L",req_schedule_conf = "general_v20_9B_rephraser",seed = -1,scale = 3.5f,ddim_steps = 16,width = 512,height = 512,use_sr = true,return_url = true,logo_info = new LogoInfo{add_logo = false,position = 0,language = 0,opacity = 0.3f,logo_text_content = "这里是明水印内容"}};string requestBody = JsonUtility.ToJson(requestData);// 生成签名string signature = GenerateSignature(timestamp, accessKey, secretKey, method, path, contentType, requestBody);//string signature = "1caf8e82d88a9fc8f094f6d800616522e7c78f23f7e4ee568625b9b825e15eb0";//Debug.Log(signature);UnityWebRequest request = new UnityWebRequest(apiUrl, method);byte[] bodyRaw = Encoding.UTF8.GetBytes(requestBody);request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();// 设置Content-Type请求头request.SetRequestHeader("Content-Type", contentType);//设置Host请求头,从API请求地址中提取主机部分//string host = new Uri(apiUrl).Host;// request.SetRequestHeader("host", host);// 设置X-Date请求头,使用获取到的时间戳转换后的格式string xDate = GetFormattedXDate(timestamp);request.SetRequestHeader("X-Date", xDate);// 计算并设置X-Content-Sha256请求头,对请求体内容计算SHA256哈希值string xContentSha256 = HashSHA256(bodyRaw);request.SetRequestHeader("X-Content-Sha256", xContentSha256);Debug.Log(xContentSha256);// 构建并设置Authorization请求头,包含签名等认证信息string credentialScope = $"{xDate.Substring(0, 8)}/{region}/{service}/request";string authorizationHeader = $"HMAC-SHA256 Credential={accessKey}/{credentialScope}, SignedHeaders=host;x-content-sha256;x-date, Signature={signature}";request.SetRequestHeader("Authorization", authorizationHeader);yield return request.SendWebRequest();// 按照新的方式判断请求结果,使用isDone和isNetworkError、isHttpError属性来替代原来的.result属性判断if (request.isDone){//// 解析返回的JSON数据,获取图片相关内容并处理显示(按文档返回格式要求操作)string responseJson = request.downloadHandler.text;Debug.Log(responseJson);ImageGenerationResponse response = JsonUtility.FromJson<ImageGenerationResponse>(responseJson);Debug.Log(response.data.binary_data_base64.Count);if (response.data.binary_data_base64 != null && response.data.binary_data_base64.Count > 0){byte[] imageBytes = System.Convert.FromBase64String(response.data.binary_data_base64[0]);Texture2D texture = new Texture2D(2, 2);texture.LoadImage(imageBytes);Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));resultImage.sprite = sprite;}else{Debug.LogError("没有获取到有效的图片数据");}}else{Debug.LogError("请求出错: " + request.error);}}public void StartImageGeneration(){StartCoroutine(GenerateImage());}private void Start(){StartImageGeneration();}
}


http://www.mrgr.cn/news/100362.html

相关文章:

  • WSL 安装过程整理
  • K8S Service 原理、案例
  • OpenCV --- 图像预处理(七)
  • Adruino:传感器及步进电机
  • 移动通信行业术语
  • 软件项目实施全流程及交付物清单
  • Android HAL HIDL
  • Happens-Before原则
  • python怎么查看函数原型及变量是什么类型
  • 高中数学联赛模拟试题精选第16套几何题
  • 学习笔记:Qlib 量化投资平台框架 — GETTING STARTED
  • Jquery -函数调用使用创建立即执行函数
  • magic-api连接达梦数据库
  • 27-算法打卡-字符串-找出字符串中第一个匹配项的下标-leetcode(28)-第二十七天
  • 当高级辅助驾驶遇上“安全驾校”:NVIDIA如何用技术给无人驾驶赋能?
  • 2:QT联合HALCON编程—图像显示放大缩小
  • classfinal 修改过源码,支持jdk17 + spring boot 3.2.8
  • 逻辑运算符
  • Leetcode刷题记录19——无重复字符的最长子串
  • 揭开人工智能的神秘面纱:从概念到人工神经网络