2025-11-16 19:33:01 +08:00

194 lines
7.0 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 Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XPrintServer.Business.Dto;
using XPrintServer.Business.Workflows.Configure;
namespace XPrintServer.Business.Workflows
{
public class QwenWorkflow : Workflow, IDisposable
{
public QwenWorkflow(ComfyUIInfos infos) : base(infos)
{
workflowPath = Path.Combine(workflowFolder, infos.Workflow.QwenImageFileName);
CheckWorkFlow();
}
// 调用ComfyUI生成图像
public async Task<string> GenerateImageAsync(string prompt, string negative_prompt, long seed, int width, int height)
{
try
{
//CheckWorkFlow();
if (seed == -1)
{
seed = new Random().NextInt64();
}
// 2. 解析并修改工作流中的提示词,宽,高
var modifiedWorkflow = ModifyWorkflow(prompt, negative_prompt, seed, width, height);
// 3. 构建API请求内容
string requestJson = "{\"client_id\":\"" + client_id + "\",\"prompt\":" + modifiedWorkflow + "}";
var content = new StringContent(requestJson, Encoding.UTF8, "application/json");
// 4. 发送POST请求到ComfyUI API
//Console.WriteLine("正在发送生成请求...");
var response = await httpClient!.PostAsync(apiUrl, content);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var result = System.Text.Json.JsonSerializer.Deserialize<ComfyUIPromptResult>(responseContent!)!;
return result.PromptId!;
}
catch (Exception ex)
{
Console.WriteLine($"发生错误: {ex.Message} {ex.InnerException}");
}
return string.Empty;
}
// 修改提示词节点100
public void UpdatePrompt(JObject workflow, string newText)
{
var node = workflow["100"]?["inputs"]?["text"] as JValue;
if (node != null && node.Type == JTokenType.String)
{
node.Value = newText;
}
else
{
throw new InvalidOperationException("未找到有效的提示词节点");
}
}
// 修改分辨率节点97
public void UpdateResolution(JObject workflow, int width, int height)
{
var node = workflow["97"]?["inputs"] as JObject;
if (node != null)
{
if (node.TryGetValue("width", out JToken? widthToken))
{
widthToken.Replace(width);
}
if (node.TryGetValue("height", out JToken? heightToken))
{
heightToken.Replace(height);
}
}
else
{
throw new InvalidOperationException("未找到分辨率节点");
}
}
// 修改KSampler节点的种子值
public void UpdateSeed(JObject workflow, long newSeed)
{
// 定位KSampler节点ID 95
var samplerNode = workflow["95"] as JObject;
if (samplerNode == null)
throw new KeyNotFoundException("未找到KSampler节点");
// 修改seed参数
JToken seedToken = samplerNode["inputs"]!["seed"]!;
if (seedToken != null && seedToken.Type == JTokenType.Integer)
{
samplerNode["inputs"]!["seed"] = newSeed;
}
else
{
throw new InvalidCastException("种子参数类型错误");
}
}
// 修改工作流中的提示词
// 修改工作流中的prompt、width、height
public string ModifyWorkflow(string newPrompt, string negative_prompt, long seed, int newWidth, int newHeight)
{
// 解析JSON为可修改的JObject
JObject workflow = JObject.Parse(workflowJson);
UpdatePrompt(workflow, newPrompt);
UpdateResolution(workflow, newWidth, newHeight);
UpdateSeed(workflow, seed);
// 返回修改后的JSON字符串
return workflow.ToString();
}
// 示例调用
//public static void Main(string[] args)
//{
// try
// {
// // 1. 加载工作流JSON文件替换为你的文件路径
// string workflowPath = "your_workflow.json";
// string originalWorkflow = File.ReadAllText(workflowPath);
// // 2. 定义新的参数
// string newPrompt = "超写实机甲金属质感暴雨场景细节丰富8K分辨率";
// int newWidth = 768; // 新宽度
// int newHeight = 1024; // 新高度
// // 3. 修改工作流
// string modifiedWorkflow = ModifyWorkflow(originalWorkflow, newPrompt, newWidth, newHeight);
// // 4. 保存修改后的工作流(可选)
// string modifiedPath = "modified_workflow.json";
// File.WriteAllText(modifiedPath, modifiedWorkflow);
// Console.WriteLine($"修改后的工作流已保存至:{modifiedPath}");
// // 5. 后续可将modifiedWorkflow发送到ComfyUI API参考之前的API调用代码
// }
// catch (Exception ex)
// {
// Console.WriteLine($"错误:{ex.Message}");
// }
//}
// 从响应中提取图像并保存
private async Task SaveImageFromResponse(System.Text.Json.JsonDocument response, string outputPath)
{
// 解析响应中的图像数据(根据实际响应结构调整)
if (response.RootElement.TryGetProperty("results", out var results))
{
foreach (var result in results.EnumerateArray())
{
if (result.TryGetProperty("data", out var data) &&
result.TryGetProperty("type", out var type) &&
type.GetString() == "image")
{
// 解码Base64图像数据
string base64Image = data.GetString()!;
byte[] imageBytes = Convert.FromBase64String(base64Image);
// 保存图像文件
await File.WriteAllBytesAsync(outputPath, imageBytes);
return;
}
}
}
throw new Exception("未从响应中找到图像数据");
}
public void Dispose()
{
if (httpClient != null)
{
httpClient.Dispose();
}
}
}
}