1. C#请求代码示例
星狐API使用文档
  • 前言
  • 如何使用星狐云API?
  • 幻墨AI画图工具使用教程
  • 星狐Claw 一键部署 OpenClaw 使用教程
  • OpenClaw配置API教程
  • Codex配置星狐云API教程
  • Claude Code配置星狐云API教程【最新】
  • Chatbox使用教程
  • Cherry Studio使用教程
  • Vscode配置API使用教程
  • Gemini CLI API配置教程
  • Cursor配置API使用教程
  • Trae配置API教程
  • N8N 工作流配置中转API 教程
  • Dify配置API教程
  • Python实例代码
  • 酒馆AI使用教程
  • Lovemo配置教程
  • 批量请求示例
  • 常见问题及解决办法
  • 售后支持
  • C#请求代码示例
    • C#调用Nano banana pro(gemini-3-pro-image-preview) 模型
  1. C#请求代码示例

C#调用Nano banana pro(gemini-3-pro-image-preview) 模型

使用默认分组,或者优质画图分组,或者酒馆ai分组

OpenAI 兼容的文生图 示例代码#

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // ====== 配置 ======
        var apiKey = "sk-xxxxxxxxxxxx"; // 换成你的apikey
        var baseUrl = "https://xinghuapi.com/v1/chat/completions";
        var model = "gemini-3-pro-image-preview"; // 以 /v1/models 为准
        var prompt = "生成一张:纯色背景的可爱小狐狸头像,卡通风格,高清";

        using var http = new HttpClient { Timeout = TimeSpan.FromMinutes(10) };
        http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

        var requestBody = new
        {
            model,
            messages = new object[]
            {
                new { role = "user", content = prompt }
            }
        };

        var requestJson = JsonSerializer.Serialize(requestBody);
        using var reqContent = new StringContent(requestJson, Encoding.UTF8, "application/json");

        Console.WriteLine("🚀 请求生图中...");
        using var resp = await http.PostAsync(baseUrl, reqContent);
        var responseText = await resp.Content.ReadAsStringAsync();

        Console.WriteLine($"📥 HTTP {(int)resp.StatusCode} {resp.StatusCode}");
        if (!resp.IsSuccessStatusCode)
        {
            Console.WriteLine("❌ 响应:");
            Console.WriteLine(responseText);
            return;
        }

        // 只预览一点点,避免刷屏
        Console.WriteLine("🧾 响应前200字符预览:");
        Console.WriteLine(responseText.Length > 200 ? responseText.Substring(0, 200) + "..." : responseText);

        // ====== 取出 content 字符串(你的情况就是 choices[0].message.content 是 string)======
        string? contentStr = ExtractContentString(responseText);
        if (string.IsNullOrWhiteSpace(contentStr))
        {
            Console.WriteLine("⚠️ 没取到 message.content");
            return;
        }

        // ====== 从 Markdown 或 data url 里提取 mime + base64 ======
        var (mime, base64) = ExtractDataUrlBase64(contentStr);
        if (string.IsNullOrWhiteSpace(base64))
        {
            Console.WriteLine("⚠️ 没在 content 中找到 data:image/...;base64,xxxx");
            Console.WriteLine("content预览:");
            Console.WriteLine(contentStr.Length > 300 ? contentStr.Substring(0, 300) + "..." : contentStr);
            return;
        }

        // 清理换行
        base64 = base64.Replace("\r", "").Replace("\n", "").Trim();

        // 根据 mime 决定扩展名
        var ext = mime switch
        {
            "image/jpeg" => ".jpg",
            "image/jpg"  => ".jpg",
            "image/png"  => ".png",
            "image/webp" => ".webp",
            _            => ".png"
        };

        // 保存
        var bytes = Convert.FromBase64String(base64);
        var fileName = $"output_{DateTime.Now:yyyyMMdd_HHmmss}{ext}";
        File.WriteAllBytes(fileName, bytes);

        Console.WriteLine($"✅ 图片已保存:{Path.GetFullPath(fileName)}");
    }

    // 兼容:content 是 string / content 是 array(取第一个 string 或 object.text)
    static string? ExtractContentString(string json)
    {
        using var doc = JsonDocument.Parse(json);
        var root = doc.RootElement;

        // choices[0].message.content
        var content = root.GetProperty("choices")[0].GetProperty("message").GetProperty("content");

        if (content.ValueKind == JsonValueKind.String)
            return content.GetString();

        if (content.ValueKind == JsonValueKind.Array && content.GetArrayLength() > 0)
        {
            var first = content[0];
            if (first.ValueKind == JsonValueKind.String) return first.GetString();
            if (first.ValueKind == JsonValueKind.Object)
            {
                if (first.TryGetProperty("text", out var t) && t.ValueKind == JsonValueKind.String) return t.GetString();
                if (first.TryGetProperty("data", out var d) && d.ValueKind == JsonValueKind.String) return d.GetString();
            }
        }

        return null;
    }

    // 从以下格式提取:
    // 1) "data:image/jpeg;base64,AAAA..."
    // 2) "![image](data:image/jpeg;base64,AAAA...)"
    static (string mime, string base64) ExtractDataUrlBase64(string s)
    {
        // 先从 markdown 里抠括号
        // ![image](data:image/jpeg;base64,xxxx)
        var mdMatch = Regex.Match(s, @"!\[.*?\]\((data:image\/[a-zA-Z0-9\+\-\.]+;base64,[A-Za-z0-9\/\+\=\r\n]+)\)");
        if (mdMatch.Success)
        {
            s = mdMatch.Groups[1].Value;
        }

        // 再匹配 data url
        var m = Regex.Match(s, @"data:(image\/[a-zA-Z0-9\+\-\.]+);base64,([A-Za-z0-9\/\+\=\r\n]+)");
        if (!m.Success) return ("", "");

        var mime = m.Groups[1].Value;
        var base64 = m.Groups[2].Value;
        return (mime, base64);
    }
}

OpenAI 兼容的图生图 示例代码#

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // ====== 1) 配置(改这里) ======
        var apiKey = "sk-xxxxxxxxxxxxxxxxxxxx"; // 换成你的
        var baseUrl = "https://xinghuapi.com/v1/chat/completions";

        // 模型名:以你 /v1/models 返回为准(常见:gemini-3-pro-image-preview / xh|gemini-3-pro-image-preview)
        var model = "gemini-3-pro-image-preview";

        // 参考图本地路径
        var inputImagePath = @"D:\CursorProject\input.jpg"; // 改成你的图片路径

        // 编辑指令
        var instruction = "请在保持主体不变的前提下,把背景改成粉色渐变,并加一些可爱的星星点缀。整体更清晰,偏二次元插画风。只输出图片,不要输出文字。";

        if (!File.Exists(inputImagePath))
        {
            Console.WriteLine("❌ 找不到参考图文件:" + inputImagePath);
            return;
        }

        // ====== 2) 读取图片 → data URL ======
        var imgBytes = await File.ReadAllBytesAsync(inputImagePath);
        var imgBase64 = Convert.ToBase64String(imgBytes);
        var mime = GuessMimeType(inputImagePath);
        var dataUrl = $"data:{mime};base64,{imgBase64}";

        // ====== 3) HttpClient ======
        using var http = new HttpClient
        {
            Timeout = TimeSpan.FromMinutes(10) // 生图/图生图建议拉长
        };
        http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

        // ====== 4) OpenAI 兼容 chat/completions 请求体(图+文) ======
        // 关键:content 用数组,包含 text + image_url(data URL)
        var requestBody = new
        {
            model = model,
            messages = new object[]
            {
                new
                {
                    role = "user",
                    content = new object[]
                    {
                        new { type = "text", text = instruction },
                        new { type = "image_url", image_url = new { url = dataUrl } }
                    }
                }
            },
            temperature = 0.7
        };

        var json = JsonSerializer.Serialize(requestBody);
        using var content = new StringContent(json, Encoding.UTF8, "application/json");

        Console.WriteLine("🚀 OpenAI兼容 图生图请求中...");
        using var resp = await http.PostAsync(baseUrl, content);
        var respText = await resp.Content.ReadAsStringAsync();

        Console.WriteLine($"📥 HTTP {(int)resp.StatusCode} {resp.StatusCode}");
        if (!resp.IsSuccessStatusCode)
        {
            Console.WriteLine("❌ 请求失败,响应如下:");
            Console.WriteLine(respText);
            return;
        }

        // 不刷屏,只预览一小段
        Console.WriteLine("🧾 响应前200字符预览:");
        Console.WriteLine(respText.Length > 200 ? respText.Substring(0, 200) + "..." : respText);

        // ====== 5) 从响应中提取图片 base64 / data URL ======
        var imageInfo = TryExtractOpenAIImage(respText);

        if (imageInfo.base64 == null)
        {
            Console.WriteLine("⚠️ 没找到图片数据(可能模型只返回文字 / 或该兼容层未开启图生图)。");
            Console.WriteLine("📄 完整响应如下(用于排查):");
            Console.WriteLine(respText);
            return;
        }

        // 保存
        var ext = (imageInfo.mime ?? "").ToLowerInvariant() switch
        {
            "image/jpeg" => ".jpg",
            "image/jpg"  => ".jpg",
            "image/png"  => ".png",
            "image/webp" => ".webp",
            _            => ".png"
        };

        var outFile = $"edited_openai_{DateTime.Now:yyyyMMdd_HHmmss}{ext}";
        var outBytes = Convert.FromBase64String(imageInfo.base64);
        await File.WriteAllBytesAsync(outFile, outBytes);

        Console.WriteLine($"✅ 已保存编辑后图片:{Path.GetFullPath(outFile)}");
    }

    // ========== 工具函数 ==========

    static string GuessMimeType(string path)
    {
        var ext = Path.GetExtension(path).ToLowerInvariant();
        return ext switch
        {
            ".jpg" => "image/jpeg",
            ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".webp" => "image/webp",
            _ => "image/jpeg"
        };
    }

    /// <summary>
    /// 尝试从 OpenAI 兼容 chat/completions 的响应里提取图片。
    /// 兼容三类常见返回:
    /// 1) choices[0].message.content 是 string: "![image](data:image/jpeg;base64,xxxx)"
    /// 2) choices[0].message.content 是 array: [{image_base64:"..."}, ...] 或 {b64_json:"..."}
    /// 3) data[0].b64_json(少数实现)
    /// </summary>
    static (string? mime, string? base64) TryExtractOpenAIImage(string json)
    {
        using var doc = JsonDocument.Parse(json);
        var root = doc.RootElement;

        // A) choices[0].message.content 是 string(你的星狐云常见:Markdown 包裹 data URL)
        if (TryGet(root, out var contentEl, "choices", 0, "message", "content"))
        {
            if (contentEl.ValueKind == JsonValueKind.String)
            {
                var s = contentEl.GetString() ?? "";
                return ExtractFromMarkdownOrDataUrl(s);
            }

            // B) content 是 array:找 image_base64 / b64_json / text(data:url)
            if (contentEl.ValueKind == JsonValueKind.Array)
            {
                foreach (var part in contentEl.EnumerateArray())
                {
                    if (part.ValueKind == JsonValueKind.Object)
                    {
                        if (part.TryGetProperty("image_base64", out var ib) && ib.ValueKind == JsonValueKind.String)
                            return (null, CleanBase64(ib.GetString()));

                        if (part.TryGetProperty("b64_json", out var b64) && b64.ValueKind == JsonValueKind.String)
                            return (null, CleanBase64(b64.GetString()));

                        if (part.TryGetProperty("text", out var t) && t.ValueKind == JsonValueKind.String)
                        {
                            var r = ExtractFromMarkdownOrDataUrl(t.GetString() ?? "");
                            if (r.base64 != null) return r;
                        }

                        if (part.TryGetProperty("data", out var d) && d.ValueKind == JsonValueKind.String)
                        {
                            var r = ExtractFromMarkdownOrDataUrl(d.GetString() ?? "");
                            if (r.base64 != null) return r;
                        }
                    }

                    if (part.ValueKind == JsonValueKind.String)
                    {
                        var r = ExtractFromMarkdownOrDataUrl(part.GetString() ?? "");
                        if (r.base64 != null) return r;
                    }
                }
            }
        }

        // C) 兼容 images 风格:data[0].b64_json
        if (TryGet(root, out var b64El, "data", 0, "b64_json") && b64El.ValueKind == JsonValueKind.String)
            return (null, CleanBase64(b64El.GetString()));

        return (null, null);
    }

    static (string? mime, string? base64) ExtractFromMarkdownOrDataUrl(string s)
    {
        if (string.IsNullOrWhiteSpace(s)) return (null, null);

        // 1) Markdown: ![image](data:image/jpeg;base64,xxx)
        var md = Regex.Match(s, @"!\[.*?\]\((data:image\/[a-zA-Z0-9\+\-\.]+;base64,[A-Za-z0-9\/\+\=\r\n]+)\)");
        if (md.Success) s = md.Groups[1].Value;

        // 2) data URL: data:image/png;base64,xxx
        var m = Regex.Match(s, @"data:(image\/[a-zA-Z0-9\+\-\.]+);base64,([A-Za-z0-9\/\+\=\r\n]+)");
        if (!m.Success) return (null, null);

        var mime = m.Groups[1].Value;
        var base64 = CleanBase64(m.Groups[2].Value);
        return (mime, base64);
    }

    static string? CleanBase64(string? b64)
    {
        if (string.IsNullOrWhiteSpace(b64)) return null;
        return b64.Replace("\r", "").Replace("\n", "").Trim();
    }

    static bool TryGet(JsonElement root, out JsonElement value, params object[] path)
    {
        value = root;
        foreach (var p in path)
        {
            if (p is string key)
            {
                if (value.ValueKind != JsonValueKind.Object || !value.TryGetProperty(key, out value))
                    return false;
            }
            else if (p is int idx)
            {
                if (value.ValueKind != JsonValueKind.Array || value.GetArrayLength() <= idx)
                    return false;
                value = value[idx];
            }
            else return false;
        }
        return true;
    }
}

Gemini 原生 文生图generateContent 接口#

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var apiKey = "sk-xxxxxxx"; // 换成你的
        var url = "https://xinghuapi.com/v1beta/models/gemini-3-pro-image-preview:generateContent";

        using var http = new HttpClient
        {
            Timeout = TimeSpan.FromMinutes(10)
        };

        http.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", apiKey);

        // ===== Gemini 原生请求体 =====
        var body = new
        {
            contents = new object[]
            {
                new {
                    role = "user",
                    parts = new object[]
                    {
                        new { text = "生成一张:纯色背景的可爱小狐狸头像,卡通风格,高清" }
                    }
                }
            }
        };

        var json = JsonSerializer.Serialize(body);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        Console.WriteLine("🚀 Gemini generateContent 请求中...");
        var resp = await http.PostAsync(url, content);
        var respText = await resp.Content.ReadAsStringAsync();

        Console.WriteLine($"📥 HTTP {(int)resp.StatusCode} {resp.StatusCode}");

        if (!resp.IsSuccessStatusCode)
        {
            Console.WriteLine("❌ 请求失败:");
            Console.WriteLine(respText);
            return;
        }

        // ===== 解析 Gemini 返回 =====
        using var doc = JsonDocument.Parse(respText);

        var base64 =
            doc.RootElement
               .GetProperty("candidates")[0]
               .GetProperty("content")
               .GetProperty("parts")[0]
               .GetProperty("inlineData")
               .GetProperty("data")
               .GetString();

        var mime =
            doc.RootElement
               .GetProperty("candidates")[0]
               .GetProperty("content")
               .GetProperty("parts")[0]
               .GetProperty("inlineData")
               .GetProperty("mimeType")
               .GetString();

        var bytes = Convert.FromBase64String(base64!);

        var ext = mime switch
        {
            "image/jpeg" => ".jpg",
            "image/png" => ".png",
            "image/webp" => ".webp",
            _ => ".png"
        };

        var file = $"gemini_native_{DateTime.Now:yyyyMMdd_HHmmss}{ext}";
        File.WriteAllBytes(file, bytes);

        Console.WriteLine($"✅ 图片已保存:{Path.GetFullPath(file)}");
    }
}

Gemini 原生 图生图generateContent 接口#

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // ====== 1) 配置(改这里) ======
        var apiKey = "sk-xxxxxxxx"; // 换成你的
        var url = "https://xinghuapi.com/v1beta/models/gemini-3-pro-image-preview:generateContent";

        // 参考图路径(本地文件)
        var inputImagePath = @"D:\CursorProject\参考图.jpg"; // 改成你的图片路径
        // 修改指令(越具体越好)
        var editInstruction =
            "请在保持人物主体不变的前提下,把背景改成粉色渐变,并加一些可爱的星星点缀。画面更清晰,整体偏二次元插画风。只输出图片,不要输出文字。";

        // ====== 2) 读取参考图并转 base64 ======
        if (!File.Exists(inputImagePath))
        {
            Console.WriteLine("❌ 找不到参考图文件:" + inputImagePath);
            return;
        }

        var imageBytes = await File.ReadAllBytesAsync(inputImagePath);
        var imageBase64 = Convert.ToBase64String(imageBytes);
        var mimeType = GuessMimeType(inputImagePath); // 根据扩展名猜测

        // ====== 3) HttpClient ======
        using var http = new HttpClient
        {
            Timeout = TimeSpan.FromMinutes(10)
        };
        http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

        // ====== 4) Gemini 原生请求体:parts 同时包含「图片 + 文本指令」 ======
        var body = new
        {
            contents = new object[]
            {
                new
                {
                    role = "user",
                    parts = new object[]
                    {
                        // 先放参考图
                        new
                        {
                            inlineData = new
                            {
                                mimeType = mimeType,
                                data = imageBase64
                            }
                        },
                        // 再放编辑指令
                        new { text = editInstruction }
                    }
                }
            }
        };

        var json = JsonSerializer.Serialize(body);
        using var content = new StringContent(json, Encoding.UTF8, "application/json");

        Console.WriteLine("🚀 Gemini 图生图(参考图编辑)请求中...");
        using var resp = await http.PostAsync(url, content);
        var respText = await resp.Content.ReadAsStringAsync();

        Console.WriteLine($"📥 HTTP {(int)resp.StatusCode} {resp.StatusCode}");
        if (!resp.IsSuccessStatusCode)
        {
            Console.WriteLine("❌ 请求失败,响应如下:");
            Console.WriteLine(respText);
            return;
        }

        // ====== 5) 解析返回:遍历 parts 找 inlineData(图片) ======
        try
        {
            using var doc = JsonDocument.Parse(respText);

            var parts = doc.RootElement
                .GetProperty("candidates")[0]
                .GetProperty("content")
                .GetProperty("parts");

            string? outBase64 = null;
            string? outMime = null;
            var textTips = new StringBuilder();

            foreach (var part in parts.EnumerateArray())
            {
                // 图片输出
                if (part.TryGetProperty("inlineData", out var inline))
                {
                    if (inline.TryGetProperty("data", out var d) && d.ValueKind == JsonValueKind.String)
                        outBase64 = d.GetString();

                    if (inline.TryGetProperty("mimeType", out var m) && m.ValueKind == JsonValueKind.String)
                        outMime = m.GetString();

                    if (!string.IsNullOrWhiteSpace(outBase64))
                        break;
                }

                // 有时会返回 text 提示
                if (part.TryGetProperty("text", out var t) && t.ValueKind == JsonValueKind.String)
                {
                    var s = t.GetString();
                    if (!string.IsNullOrWhiteSpace(s))
                        textTips.AppendLine(s);
                }
            }

            if (string.IsNullOrWhiteSpace(outBase64))
            {
                Console.WriteLine("⚠️ 本次响应没有返回图片 inlineData。可能返回了文本/安全提示/模型拒绝等。");
                if (textTips.Length > 0)
                {
                    Console.WriteLine("📝 返回文本:");
                    Console.WriteLine(textTips.ToString());
                }
                else
                {
                    Console.WriteLine("(没有 text 提示)");
                }
                return;
            }

            outBase64 = outBase64.Replace("\r", "").Replace("\n", "").Trim();

            var outBytes = Convert.FromBase64String(outBase64);
            var ext = (outMime ?? "").ToLowerInvariant() switch
            {
                "image/jpeg" => ".jpg",
                "image/jpg" => ".jpg",
                "image/png" => ".png",
                "image/webp" => ".webp",
                _ => ".png"
            };

            var outFile = $"edited_{DateTime.Now:yyyyMMdd_HHmmss}{ext}";
            await File.WriteAllBytesAsync(outFile, outBytes);

            Console.WriteLine($"✅ 已保存编辑后图片:{Path.GetFullPath(outFile)}");
        }
        catch (Exception ex)
        {
            Console.WriteLine("💥 解析失败:");
            Console.WriteLine(ex);
            Console.WriteLine("📄 原始响应(用于排查):");
            Console.WriteLine(respText);
        }
    }

    static string GuessMimeType(string path)
    {
        var ext = Path.GetExtension(path).ToLowerInvariant();
        return ext switch
        {
            ".jpg" => "image/jpeg",
            ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".webp" => "image/webp",
            _ => "image/jpeg" // 不确定就用 jpeg
        };
    }
}
修改于 2025-12-17 15:26:29
上一页
售后支持
Built with