mirror of
https://github.com/DarthAffe/StableDiffusion.NET.git
synced 2025-12-12 21:38:45 +00:00
Merge pull request #16 from DarthAffe/Example
Updated example, to v2.0.0; added Image2Image to example
This commit is contained in:
commit
3259c31e23
@ -4,7 +4,8 @@ using System.IO;
|
|||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using StableDiffusion.NET.Helper.Images;
|
using HPPH;
|
||||||
|
using HPPH.System.Drawing;
|
||||||
|
|
||||||
namespace ImageCreationUI.Converter;
|
namespace ImageCreationUI.Converter;
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ public class ImageToImageSourceConverter : IValueConverter
|
|||||||
{
|
{
|
||||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
Bitmap? bitmap = (value as IImage)?.ToBitmap();
|
using Bitmap? bitmap = (value as IImage)?.ToBitmap();
|
||||||
if (bitmap == null) return null;
|
if (bitmap == null) return null;
|
||||||
|
|
||||||
using MemoryStream ms = new();
|
using MemoryStream ms = new();
|
||||||
|
|||||||
@ -1,77 +0,0 @@
|
|||||||
using System.Buffers;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using StableDiffusion.NET.Helper.Images.Colors;
|
|
||||||
using StableDiffusion.NET.Helper.Images;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace ImageCreationUI;
|
|
||||||
|
|
||||||
public static class ImageExtension
|
|
||||||
{
|
|
||||||
public static Bitmap ToBitmap(this IImage image) => image.AsRefImage<ColorRGB>().ToBitmap();
|
|
||||||
public static Bitmap ToBitmap(this Image<ColorRGB> image) => image.AsRefImage<ColorRGB>().ToBitmap();
|
|
||||||
|
|
||||||
public static unsafe Bitmap ToBitmap(this RefImage<ColorRGB> image)
|
|
||||||
{
|
|
||||||
Bitmap output = new(image.Width, image.Height, PixelFormat.Format24bppRgb);
|
|
||||||
Rectangle rect = new(0, 0, image.Width, image.Height);
|
|
||||||
BitmapData bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);
|
|
||||||
|
|
||||||
nint ptr = bmpData.Scan0;
|
|
||||||
foreach (ReadOnlyRefEnumerable<ColorRGB> row in image.Rows)
|
|
||||||
{
|
|
||||||
Span<ColorBGR> target = new((void*)ptr, bmpData.Stride);
|
|
||||||
for (int i = 0; i < row.Length; i++)
|
|
||||||
{
|
|
||||||
ColorRGB srcColor = row[i];
|
|
||||||
target[i] = new ColorBGR(srcColor.B, srcColor.G, srcColor.R);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += bmpData.Stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.UnlockBits(bmpData);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] ToPng(this IImage image)
|
|
||||||
{
|
|
||||||
using Bitmap bitmap = image.ToBitmap();
|
|
||||||
using MemoryStream ms = new();
|
|
||||||
bitmap.Save(ms, ImageFormat.Png);
|
|
||||||
|
|
||||||
return ms.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe Image<ColorRGB> ToImage(this Bitmap bitmap)
|
|
||||||
{
|
|
||||||
int width = bitmap.Width;
|
|
||||||
int height = bitmap.Height;
|
|
||||||
|
|
||||||
byte[] buffer = new byte[height * width * ColorRGB.ColorFormat.BytesPerPixel];
|
|
||||||
Span<ColorRGB> colorBuffer = MemoryMarshal.Cast<byte, ColorRGB>(buffer);
|
|
||||||
|
|
||||||
Rectangle rect = new(0, 0, bitmap.Width, bitmap.Height);
|
|
||||||
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
|
||||||
|
|
||||||
nint ptr = bmpData.Scan0;
|
|
||||||
for (int y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
Span<ColorBGR> source = new((void*)ptr, bmpData.Stride);
|
|
||||||
Span<ColorRGB> target = colorBuffer.Slice(y * width, width);
|
|
||||||
for (int x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
ColorBGR srcColor = source[x];
|
|
||||||
target[x] = new ColorRGB(srcColor.R, srcColor.G, srcColor.B);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr += bmpData.Stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmap.UnlockBits(bmpData);
|
|
||||||
|
|
||||||
return new Image<ColorRGB>(buffer, 0, 0, width, height, width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,11 +10,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="StableDiffusion.NET.Backend.Cpu" Version="1.2.0" />
|
<PackageReference Include="HPPH.System.Drawing" Version="1.0.0" />
|
||||||
<PackageReference Include="StableDiffusion.NET.Backend.Cuda" Version="1.2.0" />
|
<PackageReference Include="StableDiffusion.NET" Version="2.0.0" />
|
||||||
<PackageReference Include="StableDiffusion.NET.Backend.Rocm" Version="1.2.0" />
|
<PackageReference Include="StableDiffusion.NET.Backend.Cpu" Version="2.0.0" />
|
||||||
<PackageReference Include="StableDiffusion.NET" Version="1.2.0" />
|
<PackageReference Include="StableDiffusion.NET.Backend.Cuda" Version="2.0.0" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="8.0.4" />
|
<PackageReference Include="StableDiffusion.NET.Backend.Rocm" Version="2.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -72,30 +72,44 @@
|
|||||||
<Label Content="AntiPrompt" />
|
<Label Content="AntiPrompt" />
|
||||||
<TextBox Height="80" TextWrapping="Wrap" Text="{Binding AntiPrompt}" />
|
<TextBox Height="80" TextWrapping="Wrap" Text="{Binding AntiPrompt}" />
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
<DockPanel LastChildFill="True">
|
||||||
<Label Width="50" Content="Width" />
|
<StackPanel DockPanel.Dock="Left">
|
||||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Width}" />
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
</StackPanel>
|
<Label Width="50" Content="Width" />
|
||||||
|
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Width}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
<Label Width="50" Content="Height" />
|
<Label Width="50" Content="Height" />
|
||||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Height}" />
|
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Height}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
<Label Width="50" Content="Cfg" />
|
<Label Width="50" Content="Cfg" />
|
||||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Cfg}" />
|
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Cfg}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
<Label Width="50" Content="Steps" />
|
<Label Width="50" Content="Steps" />
|
||||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Steps}" />
|
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Steps}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||||
<Label Width="50" Content="Seed" />
|
<Label Width="50" Content="Seed" />
|
||||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Seed}" />
|
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Seed}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<DockPanel Margin="16,0,0,0" LastChildFill="True">
|
||||||
|
<Label DockPanel.Dock="Top" Content="Image2Image Source" />
|
||||||
|
<DockPanel DockPanel.Dock="Top" >
|
||||||
|
<Button DockPanel.Dock="Right" Width="24" Margin="2,0,0,0" Content="..." Command="{Binding SelectImage2ImageSourceCommand}" IsEnabled="{Binding IsReady}" />
|
||||||
|
<TextBox Text="{Binding Image2ImageSourcePath}" />
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
|
<Image Source="{Binding Image2ImageSource, Converter={StaticResource ImageToImageSourceConverter}}" />
|
||||||
|
</DockPanel>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
<Label Content="Sample-Method" />
|
<Label Content="Sample-Method" />
|
||||||
<ComboBox ItemsSource="{Binding Source={StaticResource SamplerDataSource}}" SelectedItem="{Binding SampleMethod}" />
|
<ComboBox ItemsSource="{Binding Source={StaticResource SamplerDataSource}}" SelectedItem="{Binding SampleMethod}" />
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using HPPH;
|
||||||
|
using HPPH.System.Drawing;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using StableDiffusion.NET;
|
using StableDiffusion.NET;
|
||||||
using StableDiffusion.NET.Helper.Images;
|
|
||||||
|
|
||||||
namespace ImageCreationUI;
|
namespace ImageCreationUI;
|
||||||
|
|
||||||
@ -90,6 +92,33 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||||||
set => SetProperty(ref _sampleMethod, value);
|
set => SetProperty(ref _sampleMethod, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _image2ImageSourcePath = string.Empty;
|
||||||
|
public string Image2ImageSourcePath
|
||||||
|
{
|
||||||
|
get => _image2ImageSourcePath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _image2ImageSourcePath, value))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Image2ImageSource = ImageHelper.LoadImage(value).ConvertTo<ColorRGB>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Image2ImageSource = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IImage<ColorRGB>? _image2ImageSource;
|
||||||
|
public IImage<ColorRGB>? Image2ImageSource
|
||||||
|
{
|
||||||
|
get => _image2ImageSource;
|
||||||
|
set => SetProperty(ref _image2ImageSource, value);
|
||||||
|
}
|
||||||
|
|
||||||
private IImage? _image;
|
private IImage? _image;
|
||||||
public IImage? Image
|
public IImage? Image
|
||||||
{
|
{
|
||||||
@ -130,6 +159,9 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||||||
private ActionCommand? _selectVaeCommand;
|
private ActionCommand? _selectVaeCommand;
|
||||||
public ActionCommand SelectVaeCommand => _selectVaeCommand ??= new ActionCommand(SelectVae);
|
public ActionCommand SelectVaeCommand => _selectVaeCommand ??= new ActionCommand(SelectVae);
|
||||||
|
|
||||||
|
private ActionCommand? _selectImage2ImageSourceCommand;
|
||||||
|
public ActionCommand SelectImage2ImageSourceCommand => _selectImage2ImageSourceCommand ??= new ActionCommand(SelectImage2ImageSource);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
@ -178,19 +210,35 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||||||
{
|
{
|
||||||
IsReady = false;
|
IsReady = false;
|
||||||
|
|
||||||
LogLine("Creating image ...");
|
if (Image2ImageSource == null)
|
||||||
using StableDiffusionImage? image = await Task.Run(() => _model?.TextToImage(Prompt, new StableDiffusionParameter
|
|
||||||
{
|
{
|
||||||
NegativePrompt = AntiPrompt,
|
LogLine("Creating image ...");
|
||||||
Width = Width,
|
Image = await Task.Run(() => _model?.TextToImage(Prompt, new StableDiffusionParameter
|
||||||
Height = Height,
|
{
|
||||||
CfgScale = Cfg,
|
NegativePrompt = AntiPrompt,
|
||||||
SampleSteps = Steps,
|
Width = Width,
|
||||||
Seed = Seed,
|
Height = Height,
|
||||||
SampleMethod = SampleMethod
|
CfgScale = Cfg,
|
||||||
}));
|
SampleSteps = Steps,
|
||||||
|
Seed = Seed,
|
||||||
|
SampleMethod = SampleMethod
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogLine("Manipulating image ...");
|
||||||
|
Image = await Task.Run(() => _model?.ImageToImage(Prompt, Image2ImageSource, new StableDiffusionParameter
|
||||||
|
{
|
||||||
|
NegativePrompt = AntiPrompt,
|
||||||
|
Width = Width,
|
||||||
|
Height = Height,
|
||||||
|
CfgScale = Cfg,
|
||||||
|
SampleSteps = Steps,
|
||||||
|
Seed = Seed,
|
||||||
|
SampleMethod = SampleMethod
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
Image = image?.ToImage();
|
|
||||||
LogLine("done!");
|
LogLine("done!");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -236,6 +284,19 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
|||||||
VaePath = openFileDialog.FileName;
|
VaePath = openFileDialog.FileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectImage2ImageSource()
|
||||||
|
{
|
||||||
|
IEnumerable<string> codecs = ["All Files (*.*)|*.*", .. ImageCodecInfo.GetImageDecoders().Select(c =>
|
||||||
|
{
|
||||||
|
string codecName = c.CodecName![8..].Replace("Codec", "Files").Trim();
|
||||||
|
return $"{codecName} ({c.FilenameExtension})|{c.FilenameExtension}";
|
||||||
|
})];
|
||||||
|
|
||||||
|
OpenFileDialog openFileDialog = new() { Filter = string.Join('|', codecs) };
|
||||||
|
if (openFileDialog.ShowDialog() == true)
|
||||||
|
Image2ImageSourcePath = openFileDialog.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
private void LogLine(string line, bool appendNewLine = true)
|
private void LogLine(string line, bool appendNewLine = true)
|
||||||
{
|
{
|
||||||
if (appendNewLine)
|
if (appendNewLine)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user