From 4a5bf8dfff351d17935c5784e614968bbae0f8f3 Mon Sep 17 00:00:00 2001 From: Laurent <2-naaturel@users.noreply.gitlab.example.com> Date: Tue, 17 Feb 2026 18:20:53 +0100 Subject: [PATCH] Implemented gif exportation and added some style (again) --- GifResizer/App.xaml.cs | 2 +- GifResizer/Models/Format.cs | 18 ++ GifResizer/Models/Gif.cs | 13 +- GifResizer/Models/GifData.cs | 29 ++++ GifResizer/Service/GifService.cs | 26 +++ GifResizer/Service/ResizeService.cs | 20 --- GifResizer/ViewModels/MainViewModel.cs | 57 ++++-- .../Converter/VisibleWhenNullConverter.cs | 21 +++ GifResizer/Views/MainWindow.xaml | 164 ++++++++++++------ GifResizer/Views/MainWindow.xaml.cs | 19 +- 10 files changed, 268 insertions(+), 101 deletions(-) create mode 100644 GifResizer/Models/Format.cs create mode 100644 GifResizer/Models/GifData.cs create mode 100644 GifResizer/Service/GifService.cs delete mode 100644 GifResizer/Service/ResizeService.cs create mode 100644 GifResizer/Views/Converter/VisibleWhenNullConverter.cs diff --git a/GifResizer/App.xaml.cs b/GifResizer/App.xaml.cs index 024f10c..1e99127 100644 --- a/GifResizer/App.xaml.cs +++ b/GifResizer/App.xaml.cs @@ -16,7 +16,7 @@ public partial class App : Application { base.OnStartup(e); - var viewModel = new MainViewModel(new ResizeService()); + var viewModel = new MainViewModel(new GifService()); var mainWindow = new MainWindow(viewModel); mainWindow.Show(); diff --git a/GifResizer/Models/Format.cs b/GifResizer/Models/Format.cs new file mode 100644 index 0000000..49e57fb --- /dev/null +++ b/GifResizer/Models/Format.cs @@ -0,0 +1,18 @@ +namespace GifResizer.Models; + +public class Format +{ + public Format(int width, int height) + { + Width = width; + Height = height; + Checked = true; + } + + public int Width { get; private set; } + public int Height { get; private set; } + public bool Checked { get; set; } + + public override string ToString() => $"{Width}x{Height}"; + +} \ No newline at end of file diff --git a/GifResizer/Models/Gif.cs b/GifResizer/Models/Gif.cs index cf67b93..3df0b3a 100644 --- a/GifResizer/Models/Gif.cs +++ b/GifResizer/Models/Gif.cs @@ -1,6 +1,4 @@ -using System.Diagnostics; -using System.IO; -using GifResizer.Service; +using System.IO; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Processing; @@ -9,7 +7,7 @@ namespace GifResizer.Models; public class Gif : IDisposable { - private readonly FileInfo _file; + private readonly string _path; private Image? _image; public Gif(string path) @@ -17,18 +15,19 @@ public class Gif : IDisposable ArgumentNullException.ThrowIfNull(path); if (path.Length == 0 || path.IsWhiteSpace() || !File.Exists(path)) throw new ArgumentException($"File '{path}' does not exist"); - - _file = new FileInfo(path); + _path = path; } public void Load() { - _image = Image.Load(_file.FullName); + _image = Image.Load(_path); } public void Resize(int width, int height) { if(_image == null) throw new InvalidOperationException("Image hasn't been loaded yet"); + if(width <= 0 || height <= 0) throw new InvalidOperationException("Please specify a valid width or height."); + if(width == _image.Width && height == _image.Height) return; _image.Mutate(x => x.Resize(width, height)); } diff --git a/GifResizer/Models/GifData.cs b/GifResizer/Models/GifData.cs new file mode 100644 index 0000000..2877116 --- /dev/null +++ b/GifResizer/Models/GifData.cs @@ -0,0 +1,29 @@ +using System.IO; +using SixLabors.ImageSharp; + +namespace GifResizer.Models; + +public class GifData +{ + public GifData(string path) + { + Load(path); + } + + private void Load(string path) + { + ArgumentNullException.ThrowIfNull(path); + if (path.Length == 0 || path.IsWhiteSpace() || !File.Exists(path)) + throw new ArgumentException($"File '{path}' does not exist"); + + using Image image = Image.Load(path); + Path = path; + Width = image.Width; + Height = image.Height; + } + + public string Path { get; private set; } + public int Width { get; private set; } + public int Height { get; private set; } + +} \ No newline at end of file diff --git a/GifResizer/Service/GifService.cs b/GifResizer/Service/GifService.cs new file mode 100644 index 0000000..5afc3ca --- /dev/null +++ b/GifResizer/Service/GifService.cs @@ -0,0 +1,26 @@ +using System.IO; +using GifResizer.Models; + +namespace GifResizer.Service; + +public class GifService +{ + + public GifService() + { + + } + + public GifData GetData(string filePath) + { + return new GifData(filePath); + } + + public void ResizeGif(string filePath, int width, int height) + { + using Gif gif = new Gif(filePath); + gif.Load(); + gif.Resize(width, height); + gif.Save(Path.Combine(Directory.GetCurrentDirectory(), "output", $"{width}x{height}.gif")); + } +} \ No newline at end of file diff --git a/GifResizer/Service/ResizeService.cs b/GifResizer/Service/ResizeService.cs deleted file mode 100644 index 0a7021a..0000000 --- a/GifResizer/Service/ResizeService.cs +++ /dev/null @@ -1,20 +0,0 @@ -using GifResizer.Models; - -namespace GifResizer.Service; - -public class ResizeService -{ - - public ResizeService() - { - - } - - public void ResizeGif(string filePath, int width, int height) - { - using Gif gif = new Gif(filePath); - gif.Load(); - gif.Resize(width, height); - gif.Save("D:/test-output.gif"); - } -} \ No newline at end of file diff --git a/GifResizer/ViewModels/MainViewModel.cs b/GifResizer/ViewModels/MainViewModel.cs index fb4b95b..458caca 100644 --- a/GifResizer/ViewModels/MainViewModel.cs +++ b/GifResizer/ViewModels/MainViewModel.cs @@ -1,33 +1,62 @@ using System.ComponentModel; -using System.IO; using System.Runtime.CompilerServices; using GifResizer.Models; using GifResizer.Service; namespace GifResizer.ViewModels; -public class MainViewModel : INotifyPropertyChanged +public sealed class MainViewModel : INotifyPropertyChanged { - - private readonly ResizeService _resizeService; + private readonly GifService _gifService; public event PropertyChangedEventHandler? PropertyChanged; - public MainViewModel(ResizeService service) + public MainViewModel(GifService service) { - _resizeService = service; - FilePath = Directory.GetCurrentDirectory(); + _gifService = service; + CommonFormats = [ + new Format(112, 112), + new Format(500, 500), + new Format(1000, 1000) + ]; + FilePath = null; } - - - public string FilePath + + public string? FilePath + { + get; + set => SetField(ref field, value); + } + + public int? GifWidth + { + get; + set => SetField(ref field, value); + } + + public int? GifHeight { get; set => SetField(ref field, value); } - public void ResizeGif(int width, int height) + public List CommonFormats { get; } + + public void LoadGifData(string filePath) { - _resizeService.ResizeGif(FilePath, width, height); + GifData data = _gifService.GetData(filePath); + FilePath = filePath; + GifWidth = data.Width; + GifHeight = data.Height; + } + + public void ResizeGif() + { + if(FilePath == null && GifWidth == null && GifHeight == null) return; + _gifService.ResizeGif(FilePath!, GifWidth!.Value, GifHeight!.Value); + CommonFormats + .Where(f => f.Checked) + .ToList() + .ForEach(f => _gifService.ResizeGif(FilePath!, f.Width, f.Height)); } private bool SetField(ref T field, T value, [CallerMemberName] string? propertyName = null) @@ -37,8 +66,8 @@ public class MainViewModel : INotifyPropertyChanged OnPropertyChanged(propertyName); return true; } - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + + private void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } diff --git a/GifResizer/Views/Converter/VisibleWhenNullConverter.cs b/GifResizer/Views/Converter/VisibleWhenNullConverter.cs new file mode 100644 index 0000000..c7d36c2 --- /dev/null +++ b/GifResizer/Views/Converter/VisibleWhenNullConverter.cs @@ -0,0 +1,21 @@ +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace GifResizer.Views.Converter; + +public class VisibleWhenNullConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + bool invert = parameter?.ToString() == "invert"; + bool isVisible = invert ? value != null : value == null; + + return isVisible ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/GifResizer/Views/MainWindow.xaml b/GifResizer/Views/MainWindow.xaml index bab5460..1e99b34 100644 --- a/GifResizer/Views/MainWindow.xaml +++ b/GifResizer/Views/MainWindow.xaml @@ -4,70 +4,124 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:gif="http://wpfanimatedgif.codeplex.com" + xmlns:converter="clr-namespace:GifResizer.Views.Converter" mc:Ignorable="d" Title="Gif resizer" Height="480" Width="640" ResizeMode="NoResize"> - + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + Location + + + + + + + + + + + + + + Width + Height + + + + + + + + + + Common formats + + + + + + + + + + + + + + +