diff --git a/PhotoLocator/BitmapOperations/IIRSmoothOperation.cs b/PhotoLocator/BitmapOperations/IIRSmoothOperation.cs index 180c696..55b76ed 100644 --- a/PhotoLocator/BitmapOperations/IIRSmoothOperation.cs +++ b/PhotoLocator/BitmapOperations/IIRSmoothOperation.cs @@ -1,8 +1,7 @@ using System.Diagnostics; -using System.Threading.Tasks; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; using System.Numerics; +using System.Runtime.Intrinsics; +using System.Threading.Tasks; namespace PhotoLocator.BitmapOperations { diff --git a/PhotoLocator/JpegTransformCommands.cs b/PhotoLocator/ImageTransformCommands.cs similarity index 80% rename from PhotoLocator/JpegTransformCommands.cs rename to PhotoLocator/ImageTransformCommands.cs index ab494d7..1705c1f 100644 --- a/PhotoLocator/JpegTransformCommands.cs +++ b/PhotoLocator/ImageTransformCommands.cs @@ -12,7 +12,7 @@ namespace PhotoLocator { - public sealed class JpegTransformCommands + public sealed class ImageTransformCommands { public const string AstroCommandParameter = "Astro"; @@ -20,7 +20,7 @@ public sealed class JpegTransformCommands private bool HasFileSelected(object? o) => _mainViewModel.SelectedItem is not null && _mainViewModel.SelectedItem.IsFile; - public JpegTransformCommands(IMainViewModel mainViewModel) + public ImageTransformCommands(IMainViewModel mainViewModel) { _mainViewModel = mainViewModel; } @@ -200,5 +200,46 @@ await _mainViewModel.RunProcessWithProgressBarAsync((progressCallback, ct) => Ta } }, ct), "Batch process"); } + + public ICommand ConvertFileFormatCommand => new RelayCommand(async o => + { + var allSelected = _mainViewModel.GetSelectedItems(true).ToArray(); + if (allSelected.Length == 0) + return; + var targetType = o as string ?? throw new ArgumentException("Invalid target type"); + + var browser = new System.Windows.Forms.FolderBrowserDialog(); + browser.InitialDirectory = Path.GetDirectoryName(allSelected[0].FullPath)!; + browser.Description = $"Select target folder for converted {targetType} files"; + browser.UseDescriptionForTitle = true; + if (browser.ShowDialog() != System.Windows.Forms.DialogResult.OK) + return; + var targetDir = browser.SelectedPath; + var targetIsSourceDir = string.Equals(targetDir, browser.InitialDirectory, StringComparison.OrdinalIgnoreCase); + + await _mainViewModel.RunProcessWithProgressBarAsync(async (progressCallback, ct) => + { + var overwriteAll = false; + int i = 0; + foreach (var item in allSelected) + { + var targetFileName = targetIsSourceDir ? Path.ChangeExtension(item.GetProcessedFileName(), targetType) + : Path.Combine(targetDir, Path.GetFileNameWithoutExtension(item.Name) + "." + targetType); + if (!overwriteAll && File.Exists(targetFileName)) + { + if (MessageBox.Show(App.Current.MainWindow, $"File {targetFileName} already exists. Overwrite all conflicting files?", + "Confirm Overwrite All", MessageBoxButton.OKCancel, MessageBoxImage.Question) != MessageBoxResult.OK) + break; + overwriteAll = true; + } + + var (image, itemMetadata) = await LoadImageWithMetadataAsync(item); + await Task.Run(() => GeneralFileFormatHandler.SaveToFile(image, targetFileName, + ExifHandler.ResetOrientation(itemMetadata), _mainViewModel.Settings.JpegQuality), ct); + + progressCallback((double)(++i) / allSelected.Length); + } + }, "Convert to " + targetType); + }); } } diff --git a/PhotoLocator/MainViewModel.cs b/PhotoLocator/MainViewModel.cs index 1674416..280d35d 100644 --- a/PhotoLocator/MainViewModel.cs +++ b/PhotoLocator/MainViewModel.cs @@ -1073,7 +1073,7 @@ await ExifTool.SetTimestampAsync(item.FullPath, item.GetProcessedFileName(), tim if (SelectedItem is not null && SelectedItem.IsVideo) VideoTransformCommandsShared.CropSelected(cropRectangle); else - await JpegTransformCommands.CropSelectedItemAsync(PreviewPictureSource, cropRectangle); + await ImageTransformCommands.CropSelectedItemAsync(PreviewPictureSource, cropRectangle); } else { @@ -1087,7 +1087,7 @@ await ExifTool.SetTimestampAsync(item.FullPath, item.GetProcessedFileName(), tim public ICommand ToggleLogCommand => new RelayCommand(o => LogViewHeight = LogViewHeight > 4 ? 4 : 100); - public JpegTransformCommands JpegTransformCommands => field ??= new(this); + public ImageTransformCommands ImageTransformCommands => field ??= new(this); public VideoTransformCommands VideoTransformCommands => new(this); diff --git a/PhotoLocator/MainWindow.xaml b/PhotoLocator/MainWindow.xaml index c855d04..d5eef7c 100644 --- a/PhotoLocator/MainWindow.xaml +++ b/PhotoLocator/MainWindow.xaml @@ -31,11 +31,11 @@ - + - + @@ -119,7 +119,7 @@ ToolTip="Rename (F2)" Width="32" />