stable-diffusion.cpp 一个文件解决stable-diffusion所有环境,不需要python,stable-diffusion.dll动态库C#调用Demo

目录

介绍

效果

Text To Image

Image To Image

Upscale

项目

代码

Native.cs

SDHelper.cs

MainForm.cs

下载 

介绍

stable-diffusion.cpp 地址:https://github.com/leejet/stable-diffusion.cpp

StableDiffusionSharp 地址:https://github.com/IntptrMax/StableDiffusionSharp

测试模型下载地址:https://huggingface.co/runwayml/stable-diffusion-v1-5

放大模型下载地址:https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth

效果

Text To Image

Image To Image

Upscale

项目

代码

Native.cs

using System; using System.Runtime.InteropServices;

namespace StableDiffusionSharp {     using static StableDiffusionSharp.Structs;     using int32_t = Int32;     using int64_t = Int64;     using SdContext = IntPtr;     using SDImagePtr = IntPtr;     using UpscalerContext = IntPtr;

    internal class Native     {         const string DllName = "stable-diffusion";

        internal delegate void SdLogCallback(SdLogLevel level, [MarshalAs(UnmanagedType.LPStr)] string text, IntPtr data);         internal delegate void SdProgressCallback(int step, int steps, float time, IntPtr data);

        [DllImport(DllName, EntryPoint = "new_sd_ctx", CallingConvention = CallingConvention.Cdecl)]         internal extern static SdContext new_sd_ctx(string model_path,                                                      string vae_path,                                                      string taesd_path,                                                      string control_net_path_c_str,                                                      string lora_model_dir,                                                      string embed_dir_c_str,                                                      string stacked_id_embed_dir_c_str,                                                      bool vae_decode_only,                                                      bool vae_tiling,                                                      bool free_params_immediately,                                                      int n_threads,                                                      WeightType weightType,                                                      RngType rng_type,                                                      ScheduleType s,                                                      bool keep_clip_on_cpu,                                                      bool keep_control_net_cpu,                                                      bool keep_vae_on_cpu);

        [DllImport(DllName, EntryPoint = "txt2img", CallingConvention = CallingConvention.Cdecl)]         internal static extern SDImagePtr txt2img(SdContext sd_ctx,                            string prompt,                            string negative_prompt,                            int clip_skip,                            float cfg_scale,                            int width,                            int height,                            SampleMethod sample_method,                            int sample_steps,                            int64_t seed,                            int batch_count,                            SDImagePtr control_cond,                            float control_strength,                            float style_strength,                            bool normalize_input,                            string input_id_images_path);

        [DllImport(DllName, EntryPoint = "img2img", CallingConvention = CallingConvention.Cdecl)]         internal static extern SDImagePtr img2img(SdContext sd_ctx,                     SDImage init_image,                     string prompt_c_str,                     string negative_prompt_c_str,                     int clip_skip,                     float cfg_scale,                     int width,                     int height,                     SampleMethod sample_method,                     int sample_steps,                     float strength,                     int64_t seed,                     int batch_count);

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern IntPtr preprocess_canny(IntPtr imgData,                                  int width,                                  int height,                                  float high_threshold,                                  float low_threshold,                                  float weak,                                  float strong,                                  bool inverse);

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern UpscalerContext new_upscaler_ctx(string esrgan_path,                                         int n_threads,                                         WeightType wtype);

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern int32_t get_num_physical_cores();

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern void free_sd_ctx(SdContext sd_ctx);

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern void free_upscaler_ctx(UpscalerContext upscaler_ctx);

        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]         internal static extern SDImage upscale(UpscalerContext upscaler_ctx, SDImage input_image, int upscale_factor);

        [DllImport(DllName, EntryPoint = "sd_set_log_callback", CallingConvention = CallingConvention.Cdecl)]         internal static extern void sd_set_log_callback(SdLogCallback cb, IntPtr data);

        [DllImport(DllName, EntryPoint = "sd_set_progress_callback", CallingConvention = CallingConvention.Cdecl)]         internal static extern void sd_set_progress_callback(SdProgressCallback cb, IntPtr data);

    } }

using System;

using System.Runtime.InteropServices;

namespace StableDiffusionSharp

{

using static StableDiffusionSharp.Structs;

using int32_t = Int32;

using int64_t = Int64;

using SdContext = IntPtr;

using SDImagePtr = IntPtr;

using UpscalerContext = IntPtr;

internal class Native

{

const string DllName = "stable-diffusion";

internal delegate void SdLogCallback(SdLogLevel level, [MarshalAs(UnmanagedType.LPStr)] string text, IntPtr data);

internal delegate void SdProgressCallback(int step, int steps, float time, IntPtr data);

[DllImport(DllName, EntryPoint = "new_sd_ctx", CallingConvention = CallingConvention.Cdecl)]

internal extern static SdContext new_sd_ctx(string model_path,

string vae_path,

string taesd_path,

string control_net_path_c_str,

string lora_model_dir,

string embed_dir_c_str,

string stacked_id_embed_dir_c_str,

bool vae_decode_only,

bool vae_tiling,

bool free_params_immediately,

int n_threads,

WeightType weightType,

RngType rng_type,

ScheduleType s,

bool keep_clip_on_cpu,

bool keep_control_net_cpu,

bool keep_vae_on_cpu);

[DllImport(DllName, EntryPoint = "txt2img", CallingConvention = CallingConvention.Cdecl)]

internal static extern SDImagePtr txt2img(SdContext sd_ctx,

string prompt,

string negative_prompt,

int clip_skip,

float cfg_scale,

int width,

int height,

SampleMethod sample_method,

int sample_steps,

int64_t seed,

int batch_count,

SDImagePtr control_cond,

float control_strength,

float style_strength,

bool normalize_input,

string input_id_images_path);

[DllImport(DllName, EntryPoint = "img2img", CallingConvention = CallingConvention.Cdecl)]

internal static extern SDImagePtr img2img(SdContext sd_ctx,

SDImage init_image,

string prompt_c_str,

string negative_prompt_c_str,

int clip_skip,

float cfg_scale,

int width,

int height,

SampleMethod sample_method,

int sample_steps,

float strength,

int64_t seed,

int batch_count);

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern IntPtr preprocess_canny(IntPtr imgData,

int width,

int height,

float high_threshold,

float low_threshold,

float weak,

float strong,

bool inverse);

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern UpscalerContext new_upscaler_ctx(string esrgan_path,

int n_threads,

WeightType wtype);

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern int32_t get_num_physical_cores();

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern void free_sd_ctx(SdContext sd_ctx);

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern void free_upscaler_ctx(UpscalerContext upscaler_ctx);

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]

internal static extern SDImage upscale(UpscalerContext upscaler_ctx, SDImage input_image, int upscale_factor);

[DllImport(DllName, EntryPoint = "sd_set_log_callback", CallingConvention = CallingConvention.Cdecl)]

internal static extern void sd_set_log_callback(SdLogCallback cb, IntPtr data);

[DllImport(DllName, EntryPoint = "sd_set_progress_callback", CallingConvention = CallingConvention.Cdecl)]

internal static extern void sd_set_progress_callback(SdProgressCallback cb, IntPtr data);

}

}

SDHelper.cs

using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices;

namespace StableDiffusionSharp {     using static StableDiffusionSharp.Structs;     using SdContext = IntPtr;     using SDImagePtr = IntPtr;     using UpscalerContext = IntPtr;

    public class SDHelper     {         public bool IsInitialized => SdContext.Zero != sd_ctx;         public bool IsUpscalerInitialized => UpscalerContext.Zero != upscaler_ctx;

        private SdContext sd_ctx = new SdContext();         private UpscalerContext upscaler_ctx = new UpscalerContext();

        public static event EventHandler Log;         public static event EventHandler Progress;         static readonly Native.SdLogCallback sd_Log_Cb;         static readonly Native.SdProgressCallback sd_Progress_Cb;

        static SDHelper()         {             sd_Log_Cb = new Native.SdLogCallback(OnNativeLog);             Native.sd_set_log_callback(sd_Log_Cb, IntPtr.Zero);

            sd_Progress_Cb = new Native.SdProgressCallback(OnProgressRunning);             Native.sd_set_progress_callback(sd_Progress_Cb, IntPtr.Zero);

        }

        public bool Initialize(ModelParams modelParams)         {             sd_ctx = Native.new_sd_ctx(modelParams.ModelPath,                                         modelParams.VaePath,                                         modelParams.TaesdPath,                                         modelParams.ControlnetPath,                                         modelParams.LoraModelDir,                                         modelParams.EmbeddingsPath,                                         modelParams.StackedIdEmbeddingsPath,                                         modelParams.VaeDecodeOnly,                                         modelParams.VaeTiling,                                         modelParams.FreeParamsImmediately,                                         modelParams.Threads,                                         modelParams.SdType,                                         modelParams.RngType,                                         modelParams.Schedule,                                         modelParams.KeepClipOnCpu,                                         modelParams.KeepControlNetOnCpu,                                         modelParams.KeepVaeOnCpu);             return SdContext.Zero != sd_ctx;         }

        public bool InitializeUpscaler(UpscalerParams @params)         {             upscaler_ctx = Native.new_upscaler_ctx(@params.ESRGANPath, @params.Threads, @params.SdType);             return UpscalerContext.Zero != upscaler_ctx;         }

        public void FreeSD()         {             if (SdContext.Zero != sd_ctx)             {                 Native.free_sd_ctx(sd_ctx);                 sd_ctx = SdContext.Zero;             }         }

        public void FreeUpscaler()         {             if (UpscalerContext.Zero != upscaler_ctx)             {                 Native.free_upscaler_ctx(upscaler_ctx);                 upscaler_ctx = UpscalerContext.Zero;             }         }

        public Bitmap[] TextToImage(TextToImageParams textToImageParams)         {             if (!IsInitialized) throw new ArgumentNullException("Model not loaded!");

            SDImagePtr sd_Image_ptr = Native.txt2img(sd_ctx,                           textToImageParams.Prompt,                           textToImageParams.NegativePrompt,                           textToImageParams.ClipSkip,                           textToImageParams.CfgScale,                           textToImageParams.Width,                           textToImageParams.Height,                           textToImageParams.SampleMethod,                           textToImageParams.SampleSteps,                           textToImageParams.Seed,                           textToImageParams.BatchCount,                           SDImagePtr.Zero,                           textToImageParams.ControlStrength,                           textToImageParams.StyleStrength,                           textToImageParams.NormalizeInput,                           textToImageParams.InputIdImagesPath);

            Bitmap[] images = new Bitmap[textToImageParams.BatchCount];             for (int i = 0; i < textToImageParams.BatchCount; i++)             {                 SDImage sd_image = Marshal.PtrToStructure(sd_Image_ptr + i * Marshal.SizeOf());                 images[i] = GetBitmapFromSdImage(sd_image);             }             return images;         }

        public Bitmap ImageToImage(ImageToImageParams imageToImageParams)         {             if (!IsInitialized) throw new ArgumentNullException("Model not loaded!");             SDImage input_sd_image = GetSDImageFromBitmap(imageToImageParams.InputImage);

            SDImagePtr sdImgPtr = Native.img2img(sd_ctx,                   input_sd_image,                   imageToImageParams.Prompt,                   imageToImageParams.NegativePrompt,                   imageToImageParams.ClipSkip,                   imageToImageParams.CfgScale,                   imageToImageParams.Width,                   imageToImageParams.Height,                   imageToImageParams.SampleMethod,                   imageToImageParams.SampleSteps,                   imageToImageParams.Strength,                   imageToImageParams.Seed,                   imageToImageParams.BatchCount);             SDImage sdImg = Marshal.PtrToStructure(sdImgPtr);

            return GetBitmapFromSdImage(sdImg);         }

        public Bitmap UpscaleImage(Bitmap image, int upscaleFactor)         {             if (!IsUpscalerInitialized) throw new ArgumentNullException("Upscaler not loaded!");             SDImage inputSDImg = GetSDImageFromBitmap(image);             SDImage result = Native.upscale(upscaler_ctx, inputSDImg, upscaleFactor);             return GetBitmapFromSdImage(result);         }

        private Bitmap GetBitmapFromSdImage(SDImage sd_Image)         {             int width = (int)sd_Image.Width;             int height = (int)sd_Image.Height;             int channel = (int)sd_Image.Channel;             byte[] bytes = new byte[width * height * channel];             Marshal.Copy(sd_Image.Data, bytes, 0, bytes.Length);             Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);             int stride = bmp.Width * channel;             byte[] des = new byte[bytes.Length];             for (int i = 0; i < height; i++)             {                 for (int j = 0; j < width; j++)                 {                     des[stride * i + channel * j + 0] = bytes[stride * i + channel * j + 2];                     des[stride * i + channel * j + 1] = bytes[stride * i + channel * j + 1];                     des[stride * i + channel * j + 2] = bytes[stride * i + channel * j + 0];                 }             }             BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat);             Marshal.Copy(des, 0, bitmapData.Scan0, bytes.Length);             bmp.UnlockBits(bitmapData);

            return bmp;         }

        private SDImage GetSDImageFromBitmap(Bitmap bmp)         {             int width = bmp.Width;             int height = bmp.Height;             int channel = Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;             int stride = width * channel;             byte[] bytes = new byte[width * height * channel];             BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bmp.PixelFormat);             Marshal.Copy(bitmapData.Scan0, bytes, 0, bytes.Length);             bmp.UnlockBits(bitmapData);

            byte[] sdImageBytes = new byte[bytes.Length];             for (int i = 0; i < height; i++)             {                 for (int j = 0; j < width; j++)                 {                     sdImageBytes[stride * i + j * 3 + 0] = bytes[stride * i + j * 3 + 2];                     sdImageBytes[stride * i + j * 3 + 1] = bytes[stride * i + j * 3 + 1];                     sdImageBytes[stride * i + j * 3 + 2] = bytes[stride * i + j * 3 + 0];                 }             }

            SDImage sd_Image = new SDImage             {                 Width = (uint)width,                 Height = (uint)height,                 Channel = 3,                 Data = Marshal.UnsafeAddrOfPinnedArrayElement(sdImageBytes, 0),             };

            return sd_Image;         }

        private static void OnNativeLog(SdLogLevel level, string text, IntPtr data)         {             Log?.Invoke(null, new StableDiffusionEventArgs.StableDiffusionLogEventArgs { Level = level, Text = text });         }

        private static void OnProgressRunning(int step, int steps, float time, IntPtr data)         {             Progress?.Invoke(null, new StableDiffusionEventArgs.StableDiffusionProgressEventArgs { Step = step, Steps = steps, Time = time });         }

    } }

using System;

using System.Drawing;

using System.Drawing.Imaging;

using System.Runtime.InteropServices;

namespace StableDiffusionSharp

{

using static StableDiffusionSharp.Structs;

using SdContext = IntPtr;

using SDImagePtr = IntPtr;

using UpscalerContext = IntPtr;

public class SDHelper

{

public bool IsInitialized => SdContext.Zero != sd_ctx;

public bool IsUpscalerInitialized => UpscalerContext.Zero != upscaler_ctx;

private SdContext sd_ctx = new SdContext();

private UpscalerContext upscaler_ctx = new UpscalerContext();

public static event EventHandler Log;

public static event EventHandler Progress;

static readonly Native.SdLogCallback sd_Log_Cb;

static readonly Native.SdProgressCallback sd_Progress_Cb;

static SDHelper()

{

sd_Log_Cb = new Native.SdLogCallback(OnNativeLog);

Native.sd_set_log_callback(sd_Log_Cb, IntPtr.Zero);

sd_Progress_Cb = new Native.SdProgressCallback(OnProgressRunning);

Native.sd_set_progress_callback(sd_Progress_Cb, IntPtr.Zero);

}

public bool Initialize(ModelParams modelParams)

{

sd_ctx = Native.new_sd_ctx(modelParams.ModelPath,

modelParams.VaePath,

modelParams.TaesdPath,

modelParams.ControlnetPath,

modelParams.LoraModelDir,

modelParams.EmbeddingsPath,

modelParams.StackedIdEmbeddingsPath,

modelParams.VaeDecodeOnly,

modelParams.VaeTiling,

modelParams.FreeParamsImmediately,

modelParams.Threads,

modelParams.SdType,

modelParams.RngType,

modelParams.Schedule,

modelParams.KeepClipOnCpu,

modelParams.KeepControlNetOnCpu,

modelParams.KeepVaeOnCpu);

return SdContext.Zero != sd_ctx;

}

public bool InitializeUpscaler(UpscalerParams @params)

{

upscaler_ctx = Native.new_upscaler_ctx(@params.ESRGANPath, @params.Threads, @params.SdType);

return UpscalerContext.Zero != upscaler_ctx;

}

public void FreeSD()

{

if (SdContext.Zero != sd_ctx)

{

Native.free_sd_ctx(sd_ctx);

sd_ctx = SdContext.Zero;

}

}

public void FreeUpscaler()

{

if (UpscalerContext.Zero != upscaler_ctx)

{

Native.free_upscaler_ctx(upscaler_ctx);

upscaler_ctx = UpscalerContext.Zero;

}

}

public Bitmap[] TextToImage(TextToImageParams textToImageParams)

{

if (!IsInitialized) throw new ArgumentNullException("Model not loaded!");

SDImagePtr sd_Image_ptr = Native.txt2img(sd_ctx,

textToImageParams.Prompt,

textToImageParams.NegativePrompt,

textToImageParams.ClipSkip,

textToImageParams.CfgScale,

textToImageParams.Width,

textToImageParams.Height,

textToImageParams.SampleMethod,

textToImageParams.SampleSteps,

textToImageParams.Seed,

textToImageParams.BatchCount,

SDImagePtr.Zero,

textToImageParams.ControlStrength,

textToImageParams.StyleStrength,

textToImageParams.NormalizeInput,

textToImageParams.InputIdImagesPath);

Bitmap[] images = new Bitmap[textToImageParams.BatchCount];

for (int i = 0; i < textToImageParams.BatchCount; i++)

{

SDImage sd_image = Marshal.PtrToStructure(sd_Image_ptr + i * Marshal.SizeOf());

images[i] = GetBitmapFromSdImage(sd_image);

}

return images;

}

public Bitmap ImageToImage(ImageToImageParams imageToImageParams)

{

if (!IsInitialized) throw new ArgumentNullException("Model not loaded!");

SDImage input_sd_image = GetSDImageFromBitmap(imageToImageParams.InputImage);

SDImagePtr sdImgPtr = Native.img2img(sd_ctx,

input_sd_image,

imageToImageParams.Prompt,

imageToImageParams.NegativePrompt,

imageToImageParams.ClipSkip,

imageToImageParams.CfgScale,

imageToImageParams.Width,

imageToImageParams.Height,

imageToImageParams.SampleMethod,

imageToImageParams.SampleSteps,

imageToImageParams.Strength,

imageToImageParams.Seed,

imageToImageParams.BatchCount);

SDImage sdImg = Marshal.PtrToStructure(sdImgPtr);

return GetBitmapFromSdImage(sdImg);

}

public Bitmap UpscaleImage(Bitmap image, int upscaleFactor)

{

if (!IsUpscalerInitialized) throw new ArgumentNullException("Upscaler not loaded!");

SDImage inputSDImg = GetSDImageFromBitmap(image);

SDImage result = Native.upscale(upscaler_ctx, inputSDImg, upscaleFactor);

return GetBitmapFromSdImage(result);

}

private Bitmap GetBitmapFromSdImage(SDImage sd_Image)

{

int width = (int)sd_Image.Width;

int height = (int)sd_Image.Height;

int channel = (int)sd_Image.Channel;

byte[] bytes = new byte[width * height * channel];

Marshal.Copy(sd_Image.Data, bytes, 0, bytes.Length);

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);

int stride = bmp.Width * channel;

byte[] des = new byte[bytes.Length];

for (int i = 0; i < height; i++)

{

for (int j = 0; j < width; j++)

{

des[stride * i + channel * j + 0] = bytes[stride * i + channel * j + 2];

des[stride * i + channel * j + 1] = bytes[stride * i + channel * j + 1];

des[stride * i + channel * j + 2] = bytes[stride * i + channel * j + 0];

}

}

BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat);

Marshal.Copy(des, 0, bitmapData.Scan0, bytes.Length);

bmp.UnlockBits(bitmapData);

return bmp;

}

private SDImage GetSDImageFromBitmap(Bitmap bmp)

{

int width = bmp.Width;

int height = bmp.Height;

int channel = Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;

int stride = width * channel;

byte[] bytes = new byte[width * height * channel];

BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bmp.PixelFormat);

Marshal.Copy(bitmapData.Scan0, bytes, 0, bytes.Length);

bmp.UnlockBits(bitmapData);

byte[] sdImageBytes = new byte[bytes.Length];

for (int i = 0; i < height; i++)

{

for (int j = 0; j < width; j++)

{

sdImageBytes[stride * i + j * 3 + 0] = bytes[stride * i + j * 3 + 2];

sdImageBytes[stride * i + j * 3 + 1] = bytes[stride * i + j * 3 + 1];

sdImageBytes[stride * i + j * 3 + 2] = bytes[stride * i + j * 3 + 0];

}

}

SDImage sd_Image = new SDImage

{

Width = (uint)width,

Height = (uint)height,

Channel = 3,

Data = Marshal.UnsafeAddrOfPinnedArrayElement(sdImageBytes, 0),

};

return sd_Image;

}

private static void OnNativeLog(SdLogLevel level, string text, IntPtr data)

{

Log?.Invoke(null, new StableDiffusionEventArgs.StableDiffusionLogEventArgs { Level = level, Text = text });

}

private static void OnProgressRunning(int step, int steps, float time, IntPtr data)

{

Progress?.Invoke(null, new StableDiffusionEventArgs.StableDiffusionProgressEventArgs { Step = step, Steps = steps, Time = time });

}

}

}

MainForm.cs

using StableDiffusionSharp;

using System;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace StableDiffusionSharpGUI

{

public partial class MainForm : Form

{

private readonly SDHelper helper = new SDHelper();

public MainForm()

{

InitializeComponent();

}

private void Button_LoadModel_Click(object sender, EventArgs e)

{

if (Button_LoadModel.Text == "Load Model")

{

if (!helper.IsInitialized)

{

string modelPath = TextBox_ModelPath.Text;

string vaePath = TextBox_VaePath.Text;

string loraModelDir = TextBox_LoraModelDir.Text;

bool keepVaeOnCpu = CheckBox_CpuVae.Checked;

bool vaeTiling = CheckBox_VaeTiling.Checked;

if (!File.Exists(modelPath))

{

Button_LoadModel.Enabled = true;

MessageBox.Show("Cannot find the Model");

return;

}

Task.Run(() =>

{

Button_LoadModel.Invoke((Action)delegate

{

Button_LoadModel.Enabled = false;

TextBox_ModelPath.Enabled = false;

TextBox_VaePath.Enabled = false;

TextBox_LoraModelDir.Enabled = false;

CheckBox_CpuVae.Enabled = false;

CheckBox_VaeTiling.Enabled = false;

Button_ScanLoraPath.Enabled = false;

Button_ScanModelPath.Enabled = false;

Button_ScanVaePath.Enabled = false;

});

Structs.ModelParams modelParams = new Structs.ModelParams

{

ModelPath = modelPath,

VaePath = vaePath,

RngType = Structs.RngType.CUDA_RNG,

KeepVaeOnCpu = keepVaeOnCpu,

VaeTiling = vaeTiling,

LoraModelDir = loraModelDir,

};

bool result = helper.Initialize(modelParams);

Debug.WriteLine(result ? "Model loaded" : "Model not loaded");

Button_LoadModel.Invoke((Action)delegate

{

Button_LoadModel.Text = "Unload Model";

Button_LoadModel.Enabled = true;

});

});

}

}

else

{

helper.FreeSD();

Button_LoadModel.Text = "Load Model";

TextBox_ModelPath.Enabled = true;

TextBox_VaePath.Enabled = true;

TextBox_LoraModelDir.Enabled = true;

CheckBox_CpuVae.Enabled = true;

CheckBox_VaeTiling.Enabled = true;

Button_ScanLoraPath.Enabled = true;

Button_ScanModelPath.Enabled = true;

Button_ScanVaePath.Enabled = true;

}

}

private void Helper_Progress(object sender, StableDiffusionEventArgs.StableDiffusionProgressEventArgs e)

{

base.Invoke((Action)delegate

{

label11.Text = $"{e.Step}/{e.Steps}";

label14.Text = $"{e.IterationsPerSecond:f2} it/s";

ProgressBar_Progress.Value = (int)((e.Progress > 1 ? 1 : e.Progress) * 100);

});

}

private void Button_TextToImage_Click(object sender, EventArgs e)

{

if (!helper.IsInitialized)

{

MessageBox.Show("Please load Model first");

return;

}

Math.DivRem((int)NumericUpDown_Width.Value, 64, out int result1);

Math.DivRem((int)NumericUpDown_Height.Value, 64, out int result2);

if (result1 != 0 || result2 != 0)

{

MessageBox.Show("The width and height of the generated image must be a multiple of 64");

return;

}

Button_TextToImage.Enabled = false;

Button_ImageToImage.Enabled = false;

Structs.TextToImageParams textToImageParams = new Structs.TextToImageParams

{

Prompt = TextBox_Prompt.Text,

NegativePrompt = TextBox_NegativePrompt.Text,

SampleMethod = (Structs.SampleMethod)Enum.Parse(typeof(Structs.SampleMethod), ComboBox_SampleMethod.Text),

Width = (int)NumericUpDown_Width.Value,

Height = (int)NumericUpDown_Height.Value,

NormalizeInput = true,

ClipSkip = (int)NumericUpDown_ClipSkip.Value,

CfgScale = (float)NumericUpDown_CFG.Value,

SampleSteps = (int)NumericUpDown_SampleSteps.Value,

Seed = (long)NumericUpDown_Seed.Value,

};

Task.Run(() =>

{

Stopwatch stopwatch = new Stopwatch();

stopwatch.Restart();

Bitmap[] outputImages = helper.TextToImage(textToImageParams);

for (int i = 0; i < outputImages.Length; i++)

{

if (!Directory.Exists("output"))

{

Directory.CreateDirectory("output");

}

if (!Directory.Exists("./output/txt2img"))

{

Directory.CreateDirectory("./output/txt2img");

}

outputImages[i].Save($"./output/txt2img/{DateTime.Now:yyyyMMddHHmmss}-{i}.png");

}

base.Invoke((Action)delegate

{

PictureBox_OutputImage.Image = outputImages[0];

Button_TextToImage.Enabled = true;

Button_ImageToImage.Enabled = true;

});

Debug.WriteLine($"Time to elapsed: {stopwatch.ElapsedMilliseconds} ms");

});

}

private void MainForm_Load(object sender, EventArgs e)

{

SDHelper.Log += SDHelper_Log;

SDHelper.Progress += Helper_Progress;

ComboBox_SampleMethod.Items.AddRange(Enum.GetNames(typeof(Structs.SampleMethod)));

ComboBox_SampleMethod.SelectedIndex = 0;

PictureBox_InputImage.AllowDrop = true;

PictureBox_UpscaleInput.AllowDrop = true;

}

private void SDHelper_Log(object sender, StableDiffusionEventArgs.StableDiffusionLogEventArgs e)

{

Console.WriteLine($"time:{DateTime.Now}, {e.Level}: {e.Text}");

if (e.Text.Contains("vae compute"))

{

base.Invoke((Action)delegate { label12.Text = "VAE Progress"; });

}

else if (e.Text.Contains("generating image"))

{

base.Invoke((Action)delegate { label12.Text = "Generate Progress"; });

}

}

private void Button_ScanModelPath_Click(object sender, EventArgs e)

{

FileDialog fileDialog = new OpenFileDialog

{

Filter = "Safetensors Files (*.safetensors)|*.safetensors|CheckPoint Files (*.ckpt)|*.ckpt|GGUF Files (*.gguf)|*.gguf|All Files (*.*)|*.*"

};

if (fileDialog.ShowDialog() == DialogResult.OK)

{

TextBox_ModelPath.Text = fileDialog.FileName;

}

}

private void Button_ScanVaePath_Click(object sender, EventArgs e)

{

FileDialog fileDialog = new OpenFileDialog

{

Filter = "Safetensors Files (*.safetensors)|*.safetensors|CheckPoint Files (*.ckpt)|*.ckpt|GGUF Files (*.gguf)|*.gguf|All Files (*.*)|*.*"

};

if (fileDialog.ShowDialog() == DialogResult.OK)

{

TextBox_VaePath.Text = fileDialog.FileName;

}

}

private void Button_ScanLoraPath_Click(object sender, EventArgs e)

{

FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();

if (folderBrowserDialog.ShowDialog() == DialogResult.OK)

{

TextBox_LoraModelDir.Text = folderBrowserDialog.SelectedPath;

}

}

private void Button_ImageToImage_Click(object sender, EventArgs e)

{

if (!helper.IsInitialized)

{

MessageBox.Show("Please load a Model");

return;

}

if (null == PictureBox_InputImage.Image)

{

MessageBox.Show("Please select an Image");

return;

}

Bitmap inputBitmap = PictureBox_InputImage.Image.Clone() as Bitmap;

Math.DivRem(inputBitmap.Width, 64, out int result1);

Math.DivRem(inputBitmap.Height, 64, out int result2);

if (result1 != 0 || result2 != 0)

{

MessageBox.Show("The width and height of the generated image must be a multiple of 64");

return;

}

Button_TextToImage.Enabled = false;

Button_ImageToImage.Enabled = false;

Structs.ImageToImageParams imageToImageParams = new Structs.ImageToImageParams

{

InputImage = inputBitmap,

Prompt = TextBox_Prompt.Text,

NegativePrompt = TextBox_NegativePrompt.Text,

CfgScale = (float)NumericUpDown_CFG.Value,

Width = inputBitmap.Width,

Height = inputBitmap.Height,

SampleMethod = (Structs.SampleMethod)Enum.Parse(typeof(Structs.SampleMethod), ComboBox_SampleMethod.Text),

SampleSteps = (int)NumericUpDown_SampleSteps.Value,

Strength = (float)NumericUpDown_ReDrawStrength.Value,

Seed = (long)NumericUpDown_Seed.Value,

ClipSkip = (int)NumericUpDown_ClipSkip.Value,

};

Task.Run(() =>

{

Bitmap outputImage = helper.ImageToImage(imageToImageParams);

if (!Directory.Exists("output"))

{

Directory.CreateDirectory("output");

}

if (!Directory.Exists("./output/img2img"))

{

Directory.CreateDirectory("./output/img2img");

}

outputImage.Save($"./output/img2img/{DateTime.Now:yyyyMMddHHmmss}.png");

base.Invoke((Action)delegate

{

PictureBox_OutputImage.Image = outputImage;

Button_TextToImage.Enabled = true;

Button_ImageToImage.Enabled = true;

Button_TextToImage.Enabled = true;

});

});

}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)

{

helper.FreeSD();

helper.FreeUpscaler();

GC.Collect();

}

private void Button_RandomSeed_Click(object sender, EventArgs e)

{

Random random = new Random();

int randomPositiveInteger = random.Next(1, int.MaxValue);

NumericUpDown_Seed.Value = randomPositiveInteger;

}

private void PictureBox_InputImage_Click(object sender, EventArgs e)

{

OpenFileDialog openFileDialog = new OpenFileDialog

{

Filter = "Image Files (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp"

};

if (openFileDialog.ShowDialog() == DialogResult.OK)

{

Bitmap bitmap = new Bitmap(openFileDialog.FileName);

PictureBox_InputImage.Image = bitmap;

}

}

private void PictureBox_InputImage_DragEnter(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(DataFormats.FileDrop))

e.Effect = DragDropEffects.Link;

else e.Effect = DragDropEffects.None;

}

private void PictureBox_InputImage_DragDrop(object sender, DragEventArgs e)

{

string fileName = ((Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();

Bitmap bitmap = new Bitmap(fileName);

PictureBox_InputImage.Image = bitmap;

}

private void Button_ScanUpscaleModelPath_Click(object sender, EventArgs e)

{

OpenFileDialog openFileDialog = new OpenFileDialog

{

Filter = "ESRGAN Files (*.pth)|*.pth"

};

if (openFileDialog.ShowDialog() == DialogResult.OK)

{

TextBox_UpscaleModelPath.Text = openFileDialog.FileName;

}

}

private void PictureBox_UpscaleInput_DragDrop(object sender, DragEventArgs e)

{

string fileName = ((Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();

Bitmap bitmap = new Bitmap(fileName);

PictureBox_UpscaleInput.Image = bitmap;

}

private void PictureBox_UpscaleInput_DragEnter(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(DataFormats.FileDrop))

e.Effect = DragDropEffects.Link;

else e.Effect = DragDropEffects.None;

}

private void Button_Upscale_Click(object sender, EventArgs e)

{

if (string.IsNullOrEmpty(TextBox_UpscaleModelPath.Text))

{

MessageBox.Show("Please select a upscale Model");

return;

}

bool upscalerInited = helper.InitializeUpscaler(new Structs.UpscalerParams

{

ESRGANPath = TextBox_UpscaleModelPath.Text,

});

if (!upscalerInited)

{

MessageBox.Show("There is an error in loading upscale Model");

return;

}

if (PictureBox_UpscaleInput.Image == null)

{

MessageBox.Show("Please select an Image");

return;

}

Bitmap upscaleInputImage = PictureBox_UpscaleInput.Image as Bitmap;

Button_Upscale.Enabled = false;

Task.Run(() =>

{

try

{

Button_Upscale.Enabled = false;

Bitmap bitmap = helper.UpscaleImage(PictureBox_UpscaleInput.Image as Bitmap, 4);

helper.FreeUpscaler();

if (!Directory.Exists("output"))

{

Directory.CreateDirectory("output");

}

if (!Directory.Exists("./output/upscale"))

{

Directory.CreateDirectory("./output/upscale");

}

bitmap.Save($"./output/upscale/{DateTime.Now:yyyyMMddHHmmss}.png");

base.Invoke((Action)delegate { PictureBox_UpscaleOutput.Image = bitmap; });

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

finally

{

base.Invoke((Action)delegate { Button_Upscale.Enabled = true; });

helper.FreeUpscaler();

}

});

}

private void PictureBox_UpscaleInput_Click(object sender, EventArgs e)

{

OpenFileDialog openFileDialog = new OpenFileDialog

{

Filter = "Image Files (*.png, *.jpg, *.bmp)|*.png;*.jpg;*.bmp"

};

if (openFileDialog.ShowDialog() == DialogResult.OK)

{

Bitmap bitmap = new Bitmap(openFileDialog.FileName);

PictureBox_UpscaleInput.Image = bitmap;

}

}

}

}

下载 

源码下载

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: