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.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using StableDiffusion.NET.Helper.Images;
|
||||
using HPPH;
|
||||
using HPPH.System.Drawing;
|
||||
|
||||
namespace ImageCreationUI.Converter;
|
||||
|
||||
@ -13,7 +14,7 @@ public class ImageToImageSourceConverter : IValueConverter
|
||||
{
|
||||
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;
|
||||
|
||||
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>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Cpu" Version="1.2.0" />
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Cuda" Version="1.2.0" />
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Rocm" Version="1.2.0" />
|
||||
<PackageReference Include="StableDiffusion.NET" Version="1.2.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.4" />
|
||||
<PackageReference Include="HPPH.System.Drawing" Version="1.0.0" />
|
||||
<PackageReference Include="StableDiffusion.NET" Version="2.0.0" />
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Cpu" Version="2.0.0" />
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Cuda" Version="2.0.0" />
|
||||
<PackageReference Include="StableDiffusion.NET.Backend.Rocm" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -72,30 +72,44 @@
|
||||
<Label Content="AntiPrompt" />
|
||||
<TextBox Height="80" TextWrapping="Wrap" Text="{Binding AntiPrompt}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Width" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Width}" />
|
||||
</StackPanel>
|
||||
<DockPanel LastChildFill="True">
|
||||
<StackPanel DockPanel.Dock="Left">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Width" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Width}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Height" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Height}" />
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Height" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Height}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Cfg" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Cfg}" />
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Cfg" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Cfg}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Steps" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Steps}" />
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Steps" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Steps}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Seed" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Seed}" />
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,8,0,0">
|
||||
<Label Width="50" Content="Seed" />
|
||||
<TextBox HorizontalAlignment="Left" Width="60" Text="{Binding Seed}" />
|
||||
</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" />
|
||||
<ComboBox ItemsSource="{Binding Source={StaticResource SamplerDataSource}}" SelectedItem="{Binding SampleMethod}" />
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using HPPH;
|
||||
using HPPH.System.Drawing;
|
||||
using Microsoft.Win32;
|
||||
using StableDiffusion.NET;
|
||||
using StableDiffusion.NET.Helper.Images;
|
||||
|
||||
namespace ImageCreationUI;
|
||||
|
||||
@ -90,6 +92,33 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
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;
|
||||
public IImage? Image
|
||||
{
|
||||
@ -130,6 +159,9 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
private ActionCommand? _selectVaeCommand;
|
||||
public ActionCommand SelectVaeCommand => _selectVaeCommand ??= new ActionCommand(SelectVae);
|
||||
|
||||
private ActionCommand? _selectImage2ImageSourceCommand;
|
||||
public ActionCommand SelectImage2ImageSourceCommand => _selectImage2ImageSourceCommand ??= new ActionCommand(SelectImage2ImageSource);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -178,19 +210,35 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
IsReady = false;
|
||||
|
||||
LogLine("Creating image ...");
|
||||
using StableDiffusionImage? image = await Task.Run(() => _model?.TextToImage(Prompt, new StableDiffusionParameter
|
||||
if (Image2ImageSource == null)
|
||||
{
|
||||
NegativePrompt = AntiPrompt,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
CfgScale = Cfg,
|
||||
SampleSteps = Steps,
|
||||
Seed = Seed,
|
||||
SampleMethod = SampleMethod
|
||||
}));
|
||||
LogLine("Creating image ...");
|
||||
Image = await Task.Run(() => _model?.TextToImage(Prompt, new StableDiffusionParameter
|
||||
{
|
||||
NegativePrompt = AntiPrompt,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
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!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -236,6 +284,19 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
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)
|
||||
{
|
||||
if (appendNewLine)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user