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

这篇具有很好参考价值的文章主要介绍了stable-diffusion.cpp 一个文件解决stable diffusion所有环境,不需要python,stable-diffusion.dll动态库C#调用Demo。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

目录

介绍

效果

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

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

Image To Image

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

Upscale

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

项目

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

代码

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<StableDiffusionEventArgs.StableDiffusionLogEventArgs> Log;
        public static event EventHandler<StableDiffusionEventArgs.StableDiffusionProgressEventArgs> 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<SDImage>(sd_Image_ptr + i * Marshal.SizeOf<SDImage>());
                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<SDImage>(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<StableDiffusionEventArgs.StableDiffusionLogEventArgs> Log;
        public static event EventHandler<StableDiffusionEventArgs.StableDiffusionProgressEventArgs> 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<SDImage>(sd_Image_ptr + i * Marshal.SizeOf<SDImage>());
                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<SDImage>(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;
            }
        }
    }
}

下载 

源码下载文章来源地址https://www.toymoban.com/news/detail-851139.html

到了这里,关于stable-diffusion.cpp 一个文件解决stable diffusion所有环境,不需要python,stable-diffusion.dll动态库C#调用Demo的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【人工智能·Stable-Diffusion】如何体验到 Stable-Diffusion

    带大家快速体验到AI图片生成 Stable-Diffusion,包含 win本地部署 参考和 云GPU服务器体验 。 Stable Diffusion 是一种通过文字描述创造出图像的 AI 模型. 它是一个开源软件, 使得新手可以在线尝试。 Stable Diffusion 的算法需要计算机有较强的算力,默认是需要配置有英伟达的独立显卡的

    2024年02月11日
    浏览(45)
  • CentOS7上部署langchain-chatglm或stable-diffusion可能遇到的Bug的解决方案

    进入你的代码目录下 下载依赖 这里可能有的朋友会有问题会出现某些包下载不了,这里建议直接使用阿里源即可,在确定你的cuda版本之后(使用nvidia-smi确定cuda版本) 命令行执行 卸载掉刚才pip安装的版本!!!!因为此处安装的版本还缺少cuda的支持,确定卸载掉之后 执行 此处X为

    2024年02月16日
    浏览(30)
  • stable-diffusion画图

    1、在python官网 下载python3 安装 2、安装 CUDA 在安装 CUDA 之前查看nvidia版本 我的版本是11.6就在nvidia官网下载对应版本 3、在github中下载stable-diffusion-webui webui-user.bat以普通非管理员用户身份从运行 直到出现下面地址就代表运行成功 4、在浏览器输入127.0.0.1:7860生成图像 可以在h

    2024年02月11日
    浏览(31)
  • 安装stable-diffusion

    下载stable-diffusion源码 安装python 添加host 打开C:WindowsSystem32driversetchost 添加 修改launch.py 运行stable-diffusion-webui-1.2.1目录下webui-user.bat 安装时长较长,耐心等待 安装成功日志,主要是出现了地址“http://127.0.0.1:7860” 打开chrome,输入http://127.0.0.1:7860 python版本要为3.10.6版本,不

    2024年02月09日
    浏览(33)
  • Stable-diffusion安装时Can‘t load tokenizer for ‘openai/clip-vit-large-patch14‘问题解决

    如果你在安装stable-diffusion的时候遇到了这个问题,可以下载本博客的绑定资源,然后修改项目中的文件地址就可以了。 例如报错: 这是因为hugginface现在被墙了,所以直接下载无法下载。 首先创建一个文件夹,将本博文中下载的资源放进去,包括6个json文件,一个txt和一个

    2024年02月07日
    浏览(35)
  • Stable-Diffusion环境搭建

    硬件可以采用DELL R7525 搭配L4 或者T4 等等企业级显卡   环境如下: 可以看到有相应的GPU卡信息   esxi 7.u3 信息 设置GPU穿透方式    查看相应的虚拟机参数信息  PCI 设备加载穿透GPU信息 启动uefi  设置相应的参数信息 https://docs.nvidia.com/grid/latest/grid-vgpu-release-notes-vmware-vsphere/

    2024年02月09日
    浏览(82)
  • 我的stable-diffusion入门

    翻到一个感兴趣的帖子,然后开始了这段折腾 载下来用了,发现用的是cpu出图,慢的很,还是需要stable diffusion webui来做,所以就开始找资料 找模型: https://civitai.com/ https://huggingface.co/ stable diffusion webui:https://github.com/AUTOMATIC1111/stable-diffusion-webui 安装PyTorch详细过程 搭建和配

    2024年04月09日
    浏览(49)
  • Stable-Diffusion 在线部署

    1. 注册 链接:https://aistudio.baidu.com/aistudio/newbie?invitation=1sharedUserId=4982053sharedUserName=2019%E7%9F%A5%E5%90%A6 2. 复制项目: https://aistudio.baidu.com/aistudio/projectdetail/4905623 点击 Fork,复制为自己的项目 3. 点击启动项目 点击“启动环境”,选择合适的 32G版本的GPU,进入项目。 AIStudio 每天

    2024年02月11日
    浏览(39)
  • Stable-diffusion复现笔记

    目前正在学习有关扩撒模型的相关知识,最近复现了Stable-diffuison,此文主要是想记录一下整体的复现过程以及我在复现过程中出现的一些奇怪的问题以及我的处理方法。这里我的复现主要是针对官网文档实现的,并没有用到webui版本,如果是想体验Stable-diffusion可以去下载we

    2024年04月09日
    浏览(47)
  • stable-diffusion 学习笔记

    万字长篇!超全Stable Diffusion AI绘画参数及原理详解 - 知乎 参考:stable diffusion提示词语法详解 参考:Ai 绘图日常 篇二:从效果看Stable Diffusion中的采样方法_软件应用_什么值得买 大概示例: 默认是Latent算法:注意该算法在二次元风格时重绘幅度必须必须高于0.5,否则会得到模

    2024年02月20日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包