目录
说明
效果
项目
代码
下载
C# StableDiffusion StableDiffusionSharp 脱离python臃肿的环境

说明
Stable Diffusion in pure C/C++
github地址:https://github.com/leejet/stable-diffusion.cpp
C# Wrapper for StableDiffusion.cpp
github地址:https://github.com/DarthAffe/StableDiffusion.NET
效果

项目

电脑配置
AMD Ryzen 7 7735H with Radeon Graphics 3.19GHz
 NVIDIA GeForce RTX 4060 Laptop GPU
 cuda12.1+cudnn 8.8.1
代码
using NLog;
 using OpenCvSharp;
 using StableDiffusionSharp.Enums;
 using System.ComponentModel;
 using System.Drawing;
 using System.Drawing.Imaging;
 using System.IO;
 using System.Windows.Forms;
namespace StableDiffusionSharp
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
             NLog.Windows.Forms.RichTextBoxTarget.ReInitializeAllTextboxes(this);
         }
        StableDiffusionModel sd;
         ModelParameter mp;
         StableDiffusionParameter sdp;
         string modelpath = "C:\\MyStudy\\v1-5-pruned-emaonly.safetensors";
         string prompt = "";
         int progress = 0;
private static Logger _log = NLog.LogManager.GetCurrentClassLogger();
        private void button1_Click(object sender, System.EventArgs e)
         {
             prompt = txtPrompt.Text;
             if (string.IsNullOrEmpty(prompt))
             {
                 MessageBox.Show("请输入提示词!");
                 txtPrompt.Focus();
                 return;
             }
             if (pictureBox1.Image != null)
             {
                 pictureBox1.Image.Dispose();
             }
             pictureBox1.Image = null;
             button1.Enabled = false;
             progress = 0;
            //各种参数设置 TODO:从UI界面取值
             sdp.SampleSteps = 25;
             sdp.Width = 512;
             sdp.Height = 512;
             sdp.CfgScale = 7.5f;
             sdp.SampleMethod = Sampler.Euler_A;
             sdp.NegativePrompt = string.Empty;
             sdp.Seed = -1;
             sdp.Strength = 0.7f;
             sdp.ClipSkip = -1;
            sdp.ControlNet.Image = null;
             sdp.ControlNet.Strength = 0.9f;
             sdp.ControlNet.CannyPreprocess = false;
             sdp.ControlNet.CannyHighThreshold = 0.08f;
             sdp.ControlNet.CannyLowThreshold = 0.08f;
             sdp.ControlNet.CannyWeak = 0.8f;
             sdp.ControlNet.CannyStrong = 1.0f;
             sdp.ControlNet.CannyInverse = false;
            sdp.PhotoMaker.InputIdImageDirectory = string.Empty;
             sdp.PhotoMaker.StyleRatio = 20f;
             sdp.PhotoMaker.NormalizeInput = false;
            backgroundWorker1.RunWorkerAsync();
         }
        private void Form1_Load(object sender, System.EventArgs e)
         {
             //检查文件是否存在
             if (!File.Exists(modelpath))
             {
                 MessageBox.Show("文件不存在,请检查!");
                 return;
             }
            timer1.Enabled = true;
             timer1.Interval = 100;
            StableDiffusionModel.Log += StableDiffusionModel_Log;
             StableDiffusionModel.Progress += StableDiffusionModel_Progress;
         }
        private void timer1_Tick(object sender, System.EventArgs e)
         {
             mp = new ModelParameter();
             sdp = new StableDiffusionParameter();
             sd = new StableDiffusionModel(modelpath, mp);
             button1.Enabled = true;
             timer1.Enabled = false;
         }
        private void StableDiffusionModel_Progress(object sender, EventArgs.StableDiffusionProgressEventArgs e)
         {
             _log.Info($"{e.Step}|{e.Steps} taking  {e.Time}s");
             progress = (int)(e.Progress * 100);
             backgroundWorker1.ReportProgress(progress);
         }
        private void StableDiffusionModel_Log(object sender, EventArgs.StableDiffusionLogEventArgs e)
         {
             _log.Info($"{e.Text.Replace("\n", "")}");
         }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
         {
             StableDiffusionImage sdimage = sd.TextToImage(prompt, sdp);
             Mat image = new Mat(sdimage.Height, sdimage.Width, MatType.CV_8UC3, sdimage.Data);
             Cv2.CvtColor(image, image, ColorConversionCodes.BGR2RGB);
             //Cv2.ImShow("output", image);
             pictureBox1.Image = new Bitmap(image.ToMemoryStream());
         }
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
         {
             progressBar1.Value = e.ProgressPercentage;
         }
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
         {
             button1.Enabled = true;
             //progressBar1.Value = 0;
         }
        private void button2_Click(object sender, System.EventArgs e)
         {
             if (pictureBox1.Image == null)
             {
                 return;
             }
             Bitmap output = new Bitmap(pictureBox1.Image);
             SaveFileDialog sdf = new SaveFileDialog();
             sdf.Title = "保存";
             sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";
             if (sdf.ShowDialog() == DialogResult.OK)
             {
                 switch (sdf.FilterIndex)
                 {
                     case 1:
                         {
                             output.Save(sdf.FileName, ImageFormat.Jpeg);
                             break;
                         }
                     case 2:
                         {
                             output.Save(sdf.FileName, ImageFormat.Png);
                             break;
                         }
                     case 3:
                         {
                             output.Save(sdf.FileName, ImageFormat.Bmp);
                             break;
                         }
                     case 4:
                         {
                             output.Save(sdf.FileName, ImageFormat.Emf);
                             break;
                         }
                     case 5:
                         {
                             output.Save(sdf.FileName, ImageFormat.Exif);
                             break;
                         }
                     case 6:
                         {
                             output.Save(sdf.FileName, ImageFormat.Gif);
                             break;
                         }
                     case 7:
                         {
                             output.Save(sdf.FileName, ImageFormat.Icon);
                             break;
                         }
                    case 8:
                         {
                             output.Save(sdf.FileName, ImageFormat.Tiff);
                             break;
                         }
                     case 9:
                         {
                             output.Save(sdf.FileName, ImageFormat.Wmf);
                             break;
                         }
                 }
                 MessageBox.Show("保存成功,位置:" + sdf.FileName);
             }
        }
     }
 }
using NLog;
using OpenCvSharp;
using StableDiffusionSharp.Enums;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;namespace StableDiffusionSharp
{public partial class Form1 : Form{public Form1(){InitializeComponent();NLog.Windows.Forms.RichTextBoxTarget.ReInitializeAllTextboxes(this);}StableDiffusionModel sd;ModelParameter mp;StableDiffusionParameter sdp;string modelpath = "C:\\MyStudy\\v1-5-pruned-emaonly.safetensors";string prompt = "";int progress = 0;private static Logger _log = NLog.LogManager.GetCurrentClassLogger();private void button1_Click(object sender, System.EventArgs e){prompt = txtPrompt.Text;if (string.IsNullOrEmpty(prompt)){MessageBox.Show("请输入提示词!");txtPrompt.Focus();return;}if (pictureBox1.Image != null){pictureBox1.Image.Dispose();}pictureBox1.Image = null;button1.Enabled = false;progress = 0;//各种参数设置 TODO:从UI界面取值sdp.SampleSteps = 25;sdp.Width = 512;sdp.Height = 512;sdp.CfgScale = 7.5f;sdp.SampleMethod = Sampler.Euler_A;sdp.NegativePrompt = string.Empty;sdp.Seed = -1;sdp.Strength = 0.7f;sdp.ClipSkip = -1;sdp.ControlNet.Image = null;sdp.ControlNet.Strength = 0.9f;sdp.ControlNet.CannyPreprocess = false;sdp.ControlNet.CannyHighThreshold = 0.08f;sdp.ControlNet.CannyLowThreshold = 0.08f;sdp.ControlNet.CannyWeak = 0.8f;sdp.ControlNet.CannyStrong = 1.0f;sdp.ControlNet.CannyInverse = false;sdp.PhotoMaker.InputIdImageDirectory = string.Empty;sdp.PhotoMaker.StyleRatio = 20f;sdp.PhotoMaker.NormalizeInput = false;backgroundWorker1.RunWorkerAsync();}private void Form1_Load(object sender, System.EventArgs e){//检查文件是否存在if (!File.Exists(modelpath)){MessageBox.Show("文件不存在,请检查!");return;}timer1.Enabled = true;timer1.Interval = 100;StableDiffusionModel.Log += StableDiffusionModel_Log;StableDiffusionModel.Progress += StableDiffusionModel_Progress;}private void timer1_Tick(object sender, System.EventArgs e){mp = new ModelParameter();sdp = new StableDiffusionParameter();sd = new StableDiffusionModel(modelpath, mp);button1.Enabled = true;timer1.Enabled = false;}private void StableDiffusionModel_Progress(object sender, EventArgs.StableDiffusionProgressEventArgs e){_log.Info($"{e.Step}|{e.Steps} taking  {e.Time}s");progress = (int)(e.Progress * 100);backgroundWorker1.ReportProgress(progress);}private void StableDiffusionModel_Log(object sender, EventArgs.StableDiffusionLogEventArgs e){_log.Info($"{e.Text.Replace("\n", "")}");}private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){StableDiffusionImage sdimage = sd.TextToImage(prompt, sdp);Mat image = new Mat(sdimage.Height, sdimage.Width, MatType.CV_8UC3, sdimage.Data);Cv2.CvtColor(image, image, ColorConversionCodes.BGR2RGB);//Cv2.ImShow("output", image);pictureBox1.Image = new Bitmap(image.ToMemoryStream());}private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar1.Value = e.ProgressPercentage;}private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){button1.Enabled = true;//progressBar1.Value = 0;}private void button2_Click(object sender, System.EventArgs e){if (pictureBox1.Image == null){return;}Bitmap output = new Bitmap(pictureBox1.Image);SaveFileDialog sdf = new SaveFileDialog();sdf.Title = "保存";sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";if (sdf.ShowDialog() == DialogResult.OK){switch (sdf.FilterIndex){case 1:{output.Save(sdf.FileName, ImageFormat.Jpeg);break;}case 2:{output.Save(sdf.FileName, ImageFormat.Png);break;}case 3:{output.Save(sdf.FileName, ImageFormat.Bmp);break;}case 4:{output.Save(sdf.FileName, ImageFormat.Emf);break;}case 5:{output.Save(sdf.FileName, ImageFormat.Exif);break;}case 6:{output.Save(sdf.FileName, ImageFormat.Gif);break;}case 7:{output.Save(sdf.FileName, ImageFormat.Icon);break;}case 8:{output.Save(sdf.FileName, ImageFormat.Tiff);break;}case 9:{output.Save(sdf.FileName, ImageFormat.Wmf);break;}}MessageBox.Show("保存成功,位置:" + sdf.FileName);}}}
}
下载
源码下载(模型太大,需要单独下载)
模型下载
Stable Diffusion v1.4  https://huggingface.co/CompVis/stable-diffusion-v-1-4-original
 Stable Diffusion v1.5  https://huggingface.co/runwayml/stable-diffusion-v1-5
 Stable Diffuison v2.1  https://huggingface.co/stabilityai/stable-diffusion-2-1