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

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

View File

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

View File

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