Skip to content

Commit 278eff9

Browse files
committed
Upscale Demo App
1 parent 647d0eb commit 278eff9

File tree

112 files changed

+12083
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+12083
-9
lines changed

.gitignore

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,9 @@ test/TensorFlowNET.Examples/mnist
345345

346346
# docs
347347
site/
348-
349-
/OnnxStack.WebUI/wwwroot/images/Results/*
350348
docker-test-output/*
351349

352-
Examples/*
353-
TensorStack.WPF/*
354-
TensorStackFull.sln
350+
Examples/TensorStack.Console*
355351
TensorStack.Diffusers/*
356352
TensorStudio/*
353+
/TensorStackFull.sln
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<Application x:Class="TensorStack.Example.Upscaler.App"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:local="clr-namespace:TensorStack.Example.Upscaler"
5+
xmlns:CommonControls="clr-namespace:TensorStack.WPF.Controls;assembly=TensorStack.WPF"
6+
ShutdownMode="OnMainWindowClose">
7+
<Application.Resources>
8+
9+
10+
<ResourceDictionary>
11+
12+
<!--TensorStack.Example.Upscaler-->
13+
<Style x:Key="ImageDropZoneStyle" TargetType="{x:Type Border}">
14+
<Setter Property="AllowDrop" Value="False"/>
15+
<Setter Property="BorderBrush" Value="Transparent"/>
16+
<Setter Property="BorderThickness" Value="1"/>
17+
<Style.Triggers>
18+
<MultiDataTrigger>
19+
<MultiDataTrigger.Conditions>
20+
<Condition Binding="{Binding IsDragDrop, RelativeSource={RelativeSource AncestorType=CommonControls:ViewControl}}" Value="True" />
21+
<Condition Binding="{Binding DragDropType, RelativeSource={RelativeSource AncestorType=CommonControls:ViewControl}}" Value="Image" />
22+
</MultiDataTrigger.Conditions>
23+
<MultiDataTrigger.Setters>
24+
<Setter Property="AllowDrop" Value="True"/>
25+
<Setter Property="BorderBrush" Value="{StaticResource AccentColour2}"/>
26+
</MultiDataTrigger.Setters>
27+
</MultiDataTrigger>
28+
</Style.Triggers>
29+
</Style>
30+
31+
32+
<Style x:Key="VideoDropZoneStyle" TargetType="{x:Type Border}">
33+
<Setter Property="AllowDrop" Value="False"/>
34+
<Setter Property="BorderBrush" Value="Transparent"/>
35+
<Setter Property="BorderThickness" Value="1"/>
36+
<Style.Triggers>
37+
<MultiDataTrigger>
38+
<MultiDataTrigger.Conditions>
39+
<Condition Binding="{Binding IsDragDrop, RelativeSource={RelativeSource AncestorType=CommonControls:ViewControl}}" Value="True" />
40+
<Condition Binding="{Binding DragDropType, RelativeSource={RelativeSource AncestorType=CommonControls:ViewControl}}" Value="Video" />
41+
</MultiDataTrigger.Conditions>
42+
<MultiDataTrigger.Setters>
43+
<Setter Property="AllowDrop" Value="True"/>
44+
<Setter Property="BorderBrush" Value="{StaticResource AccentColour2}"/>
45+
</MultiDataTrigger.Setters>
46+
</MultiDataTrigger>
47+
</Style.Triggers>
48+
</Style>
49+
50+
<!--TensorStack.WPF-->
51+
<ResourceDictionary.MergedDictionaries>
52+
<ResourceDictionary Source="pack://application:,,,/TensorStack.WPF;component/ThemeDefault.xaml" />
53+
</ResourceDictionary.MergedDictionaries>
54+
55+
</ResourceDictionary>
56+
57+
58+
</Application.Resources>
59+
</Application>
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Hosting;
3+
using System;
4+
using System.IO;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Threading;
8+
using TensorStack.WPF;
9+
using TensorStack.Example.Services;
10+
11+
namespace TensorStack.Example.Upscaler
12+
{
13+
/// <summary>
14+
/// Interaction logic for App.xaml
15+
/// </summary>
16+
public partial class App : Application
17+
{
18+
private readonly IHost _appHost;
19+
20+
public App()
21+
{
22+
RegisterExceptionHandlers();
23+
24+
var builder = Host.CreateApplicationBuilder();
25+
26+
var configuration = Json.Load<Settings>("Settings.json");
27+
configuration.Initialize();
28+
29+
// Add WPFCommon
30+
builder.Services.AddWPFCommon<MainWindow, Settings>(configuration);
31+
32+
builder.Services.AddSingleton<IMediaService, MediaService>();
33+
builder.Services.AddSingleton<IUpscaleService, UpscaleService>();
34+
builder.Services.AddSingleton<IInterpolationService, InterpolationService>();
35+
36+
_appHost = builder.Build();
37+
38+
// Initialize WPFCommon
39+
_appHost.Services.UseWPFCommon();
40+
}
41+
42+
43+
/// <summary>
44+
/// Application startup.
45+
/// </summary>
46+
/// <returns>Task.</returns>
47+
private Task AppStartup()
48+
{
49+
MainWindow = _appHost.Services.GetMainWindow();
50+
MainWindow.Show();
51+
return Task.CompletedTask;
52+
}
53+
54+
55+
/// <summary>
56+
/// Application shutdown.
57+
/// </summary>
58+
private async Task AppShutdown()
59+
{
60+
using (_appHost)
61+
{
62+
await _appHost.StopAsync();
63+
DeregisterExceptionHandlers();
64+
}
65+
}
66+
67+
68+
/// <summary>
69+
/// Raises the <see cref="E:System.Windows.Application.Startup" /> event.
70+
/// </summary>
71+
/// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param>
72+
protected override async void OnStartup(StartupEventArgs e)
73+
{
74+
await AppStartup();
75+
base.OnStartup(e);
76+
}
77+
78+
79+
/// <summary>
80+
/// Raises the <see cref="E:System.Windows.Application.SessionEnding" /> event.
81+
/// </summary>
82+
/// <param name="e">A <see cref="T:System.Windows.SessionEndingCancelEventArgs" /> that contains the event data.</param>
83+
protected override async void OnSessionEnding(SessionEndingCancelEventArgs e)
84+
{
85+
await AppShutdown();
86+
base.OnSessionEnding(e);
87+
}
88+
89+
90+
/// <summary>
91+
/// Raises the <see cref="E:System.Windows.Application.Exit" /> event.
92+
/// </summary>
93+
/// <param name="e">An <see cref="T:System.Windows.ExitEventArgs" /> that contains the event data.</param>
94+
protected async override void OnExit(ExitEventArgs e)
95+
{
96+
await AppShutdown();
97+
base.OnExit(e);
98+
}
99+
100+
101+
/// <summary>
102+
/// Registers the exception handlers.
103+
/// </summary>
104+
private void RegisterExceptionHandlers()
105+
{
106+
DispatcherUnhandledException += OnDispatcherException;
107+
AppDomain.CurrentDomain.UnhandledException += OnAppDomainException;
108+
TaskScheduler.UnobservedTaskException += OnTaskSchedulerException;
109+
}
110+
111+
112+
/// <summary>
113+
/// Deregisters the exception handlers.
114+
/// </summary>
115+
private void DeregisterExceptionHandlers()
116+
{
117+
DispatcherUnhandledException -= OnDispatcherException;
118+
AppDomain.CurrentDomain.UnhandledException -= OnAppDomainException;
119+
TaskScheduler.UnobservedTaskException -= OnTaskSchedulerException;
120+
}
121+
122+
123+
/// <summary>
124+
/// Handles the <see cref="E:DispatcherException" /> event.
125+
/// </summary>
126+
/// <param name="sender">The sender.</param>
127+
/// <param name="e">The <see cref="DispatcherUnhandledExceptionEventArgs"/> instance containing the event data.</param>
128+
private void OnDispatcherException(object sender, DispatcherUnhandledExceptionEventArgs e)
129+
{
130+
ShowExceptionMessage(e.Exception);
131+
132+
// Prevent application from crashing
133+
e.Handled = true;
134+
}
135+
136+
137+
/// <summary>
138+
/// Handles the <see cref="E:AppDomainException" /> event.
139+
/// </summary>
140+
/// <param name="sender">The sender.</param>
141+
/// <param name="e">The <see cref="UnhandledExceptionEventArgs"/> instance containing the event data.</param>
142+
private void OnAppDomainException(object sender, UnhandledExceptionEventArgs e)
143+
{
144+
if (e.ExceptionObject is Exception ex)
145+
{
146+
ShowExceptionMessage(ex);
147+
}
148+
}
149+
150+
151+
/// <summary>
152+
/// Handles the <see cref="E:TaskSchedulerException" /> event.
153+
/// </summary>
154+
/// <param name="sender">The sender.</param>
155+
/// <param name="e">The <see cref="UnobservedTaskExceptionEventArgs"/> instance containing the event data.</param>
156+
private void OnTaskSchedulerException(object sender, UnobservedTaskExceptionEventArgs e)
157+
{
158+
ShowExceptionMessage(e.Exception);
159+
160+
// Prevent application from crashing
161+
e.SetObserved();
162+
}
163+
164+
165+
private void ShowExceptionMessage(Exception ex)
166+
{
167+
MessageBox.Show($"An unexpected error occurred:\n{ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
168+
}
169+
}
170+
}
171+
172+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Windows;
2+
3+
[assembly: ThemeInfo(
4+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5+
//(used if a resource is not found in the page,
6+
// or application resource dictionaries)
7+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8+
//(used if a resource is not found in the page,
9+
// app, or any theme specific resource dictionaries)
10+
)]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using TensorStack.Common;
2+
using TensorStack.WPF;
3+
4+
namespace TensorStack.Example.Common
5+
{
6+
7+
public class UpscaleModel : BaseModel
8+
{
9+
public int Id { get; init; }
10+
public string Name { get; init; }
11+
public bool IsDefault { get; set; }
12+
13+
public int Channels { get; init; } = 3;
14+
public int SampleSize { get; init; }
15+
public int ScaleFactor { get; init; } = 1;
16+
public Normalization Normalization { get; init; }
17+
public string Path { get; set; }
18+
}
19+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.IO;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
using System.Threading.Tasks;
5+
using TensorStack.Example.Common;
6+
7+
namespace TensorStack.Example
8+
{
9+
public static class Json
10+
{
11+
public readonly static JsonSerializerOptions DefaultOptions;
12+
13+
static Json()
14+
{
15+
DefaultOptions = new JsonSerializerOptions
16+
{
17+
WriteIndented = true,
18+
Converters = { new JsonStringEnumConverter() }
19+
};
20+
}
21+
22+
23+
public static T Load<T>(string filePath) where T : class
24+
{
25+
try
26+
{
27+
using (var jsonReader = File.OpenRead(filePath))
28+
{
29+
return JsonSerializer.Deserialize<T>(jsonReader, DefaultOptions);
30+
}
31+
}
32+
catch (System.Exception)
33+
{
34+
return default;
35+
}
36+
37+
}
38+
39+
40+
public static async Task<T> LoadAsync<T>(string filePath) where T : class
41+
{
42+
try
43+
{
44+
using (var jsonReader = File.OpenRead(filePath))
45+
{
46+
return await JsonSerializer.DeserializeAsync<T>(jsonReader, DefaultOptions);
47+
}
48+
}
49+
catch (System.Exception)
50+
{
51+
return default;
52+
}
53+
}
54+
}
55+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<CommonControls:WindowMainBase x:Class="TensorStack.Example.Upscaler.MainWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:local="clr-namespace:TensorStack.Example.Upscaler"
7+
xmlns:CommonControls="clr-namespace:TensorStack.WPF.Controls;assembly=TensorStack.WPF"
8+
xmlns:Views="clr-namespace:TensorStack.Example.Views"
9+
Style="{StaticResource WindowHeadless}"
10+
Icon="{StaticResource ImageIcon}"
11+
mc:Ignorable="d"
12+
x:Name="UI"
13+
Title="MainWindow" Height="680" Width="1100">
14+
<DockPanel DataContext="{Binding ElementName=UI}">
15+
16+
<!--Main Menu-->
17+
<Grid DockPanel.Dock="Top" WindowChrome.IsHitTestVisibleInChrome="True">
18+
<UniformGrid Columns="5" Height="30" Margin="2">
19+
20+
<!--Logo-->
21+
<Grid IsHitTestVisible="False">
22+
<Image Source="{StaticResource ImageTensorstackText}" Height="32" HorizontalAlignment="Left" Margin="4,2,50,0" />
23+
</Grid>
24+
25+
<!--Views-->
26+
<Button Command="{Binding NavigateCommand}" CommandParameter="{x:Static Views:View.ImageUpscale}" Content="Image Upscale" />
27+
<Button Command="{Binding NavigateCommand}" CommandParameter="{x:Static Views:View.VideoUpscale}" Content="Video Upscale" />
28+
<Button Command="{Binding NavigateCommand}" CommandParameter="{x:Static Views:View.Interpolation}" Content="Frame Interpolation" />
29+
30+
<!--Window Options-->
31+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
32+
<UniformGrid Columns="3" >
33+
<Button Command="{Binding MinimizeCommand}" Padding="10,1" >
34+
<CommonControls:FontAwesome Icon="&#xf2d1;" />
35+
</Button>
36+
<Grid>
37+
<Button Command="{Binding RestoreCommand}" Padding="10,1" Visibility="{Binding WindowState, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter=Maximized}">
38+
<CommonControls:FontAwesome Icon="&#xf2d2;" />
39+
</Button>
40+
<Button Command="{Binding MaximizeCommand}" Padding="10,1" Visibility="{Binding WindowState, Converter={StaticResource InverseEnumToVisibilityConverter}, ConverterParameter=Maximized}">
41+
<CommonControls:FontAwesome Icon="&#xf2d0;" />
42+
</Button>
43+
</Grid>
44+
<Button x:Name="CloseButton" Command="{Binding CloseCommand}" Padding="12,0" >
45+
<CommonControls:FontAwesome Icon="&#xf00d;" />
46+
</Button>
47+
</UniformGrid>
48+
</StackPanel>
49+
50+
</UniformGrid>
51+
</Grid>
52+
53+
<!--View Container-->
54+
<CommonControls:ViewContainer Navigation="{Binding Navigation}" NavigationUIVisibility="Hidden"/>
55+
56+
</DockPanel>
57+
</CommonControls:WindowMainBase>

0 commit comments

Comments
 (0)