Merge pull request #16 from DarthAffe/Example

Updated example, to v2.0.0; added Image2Image to example
This commit is contained in:
DarthAffe 2024-07-22 22:07:51 +02:00 committed by GitHub
commit 3259c31e23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 115 additions and 116 deletions

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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}" />

View File

@ -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)