• 使用Unity 接入 Stable-Diffusion-WebUI的 文生图api 并生成图像


    使用Unity 接入 Stable-Diffusion-WebUI 文生图生成图像

    一、前言

    在无聊的时候,想瞅一下sd生图遂做了一下
    在这里插入图片描述
    注意:我采用了异步处理,每点击一次发送一次请求,不需要等待生成完再点击。后面生成的画面会覆盖掉之前的。

    二、具体步骤

    1、启动SD的api设置

    在这里插入图片描述

    注意,运行后的api相关功能可以在:http://127.0.0.1:7860/docs 查看
    在这里插入图片描述

    比如这一次我们要的生图的地址就是/sdapi/v1/txt2img 是POST
    所以可以通过requests 向 "http://127.0.0.1:7860/sdapi/v1/txt2img"发送POST请求并拿到数据

    注意: “http://127.0.0.1:7860/sdapi/v1/txt2img” ,里面的地址和端口在unity中改成你设置的,如果没有改就不动
    到这里sd的前期准备就OK了

    2、unity 创建生图脚本

    新建C#脚本,imgsd
    注意:

    • “http://127.0.0.1:7860/sdapi/v1/txt2img” 里面的ip和端口与sd中设置的一致
    • sd_model_name = “animePastelDream_softBakedVae” 模型用你自己的模型,如果删掉则用默认你第一个模型。模型文件如:majicmixRealistic_v7.safetensors 则模型名为majicmixRealistic_v7
    • 要用某个魔,需要在sd的web中能看到这个模型,你才能使用api调用。你需要下载模型后放在models文件夹在,参考地址如:sd-webui-aki-v4\models\Stable-diffusion

    其他的保持不动即可

    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.UI;
    using System.Text;
    using System;
    using System.Collections;
    
    
    public class imgsd : MonoBehaviour
    {
        public InputField promptInputField; // 在Inspector中设置
        public InputField negativePromptInputField; // 在Inspector中设置
        public RawImage outputImage; // 在Inspector中设置
    
        private string txt2imgUrl = "http://127.0.0.1:7860/sdapi/v1/txt2img";
    
        // 调用这个方法来开始生成图像的过程
        public void GenerateImage()
        {
            string prompt = promptInputField.text;
            string negativePrompt = negativePromptInputField.text;
            StartCoroutine(PostRequest(txt2imgUrl, prompt, negativePrompt));
        }
        [Serializable]
        public class YourResponseType
        {
            public string[] images;
            // 添加其他需要的字段
        }
    
    
        IEnumerator PostRequest(string url, string prompt, string negativePrompt)
        {
            var data = new
            {
                prompt = prompt,
                negative_prompt = negativePrompt,
                sd_model_name = "animePastelDream_softBakedVae"
            };
    
            string jsonData = JsonUtility.ToJson(data);
    
            using (UnityWebRequest www = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST))
            {
                byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);
                www.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
                www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
                www.SetRequestHeader("Content-Type", "application/json");
    
                yield return www.SendWebRequest();
    
                if (www.result != UnityWebRequest.Result.Success)
                {
                    Debug.LogError($"请求失败: {www.error}");
                }
                else
                {
                    Debug.Log("请求成功");
                    // 解析响应
                    string jsonResponse = www.downloadHandler.text;
                    YourResponseType response = JsonUtility.FromJson<YourResponseType>(jsonResponse);
                    // 假设YourResponseType是你定义的类,用来匹配JSON响应的结构
    
                    // 显示图像
                    DisplayImage(response.images[0]); // 假设images[0]包含了Base64编码的图像
                }
            }
        }
    
        private void DisplayImage(string base64String)
        {
            byte[] bytes = Convert.FromBase64String(base64String);
            Texture2D texture = new Texture2D(2, 2);
            if (texture.LoadImage(bytes))
            {
                outputImage.texture = texture;
            }
            else
            {
                Debug.LogError("图像加载失败");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    3、Unity 生图交互配置

    要通过点击事件触发GenerateImage方法,你可以使用Unity的UI系统中的按钮(Button)组件。这里有一个简单的步骤说明如何做到这一点:

    步骤 1: 创建sdControl
    1. 在Unity编辑器中,右键点击Hierarchy面板中的空白区域。
    2. 创建一个空对象Create Empty,并改名为sdcontrol。
    3. 将上一步创建的imgsd脚本拖拽到sdcontrol
    步骤2:生成后图片画布
    1. 在Unity编辑器中,右键点击Hierarchy面板中的空白区域。
    2. UI->Raw Image ``
    步骤3:创建两个输入框
    1. 在Unity编辑器中,右键点击Hierarchy面板中的空白区域。
    2. UI->Legacy -> input fileld ``
    3. UI->Legacy -> input fileld ``
      执行两次,创建两个输入框
      注:UI ->如果没有Legacy 那就UI -> input fileld
    步骤4:sdcontrol赋值

    在这里插入图片描述

    步骤 5: 创建按钮并绑定点击事件
    1. 在Unity编辑器中,右键点击Hierarchy面板中的空白区域。

    2. 选择UI -> Button。这将自动创建一个Canvas(如果尚未存在),button的text改为生成

    3. 选中你刚刚创建的按钮对象。

    4. 在Inspector面板中找到Button (Script)组件。

    5. 拖拽包含TextToImageRequest脚本的GameObject(即你将该脚本附加到的对象)到Button (Script)组件下方的OnClick()列表中。

    6. 点击OnClick()列表旁边的加号(+)来添加一个新的条目。

    7. 在新条目的None (Object)字段中,确保包含TextToImageRequest脚本的GameObject被选中。

    8. 然后点击旁边的下拉菜单,选择TextToImageRequest -> GenerateImage

    三、测试

    • 进入Play模式,输入prompt 点击按钮,这应该会触发GenerateImage方法,从而开始图像生成的过程。
      在这里插入图片描述

    注:如果发现生成了画面,但与实际的不符,请尝试输入另外一个框,再试着点击一次。因为两个框依次代表,prompt 和native prompt如果输错了框会导致生成效果不理想。

  • 相关阅读:
    解决Java获取数据库日期数据问题:格式为【YYYY/MM/DD】,获取的格式却转换为【YYYY-MM-DD hh:mm:ss】
    nacos 详细介绍(二)
    【Python 千题 —— 基础篇】进制转换:十进制转十六进制
    leetcode 39. 组合总和(完全背包问题)
    Kubuesphere部署Ruoyi(二):部署kubesphere
    由CPU高负载引发内核探索之旅
    cpu天梯图2022年11月 cpu排行榜天梯图2022
    对补码的简单理解
    消极型人格分析,如何改变消极型性格?
    SpringCloud OpenFeign
  • 原文地址:https://blog.csdn.net/qq_51116518/article/details/137898912