]> granicus.if.org Git - handbrake/commitdiff
WinGui: Optional support for previewing flip/rotate. #2334
authorsr55 <sr55.hb@outlook.com>
Tue, 1 Oct 2019 18:49:52 +0000 (19:49 +0100)
committersr55 <sr55.hb@outlook.com>
Tue, 1 Oct 2019 18:50:27 +0000 (19:50 +0100)
14 files changed:
win/CS/HandBrakeWPF/HandBrakeWPF.csproj
win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
win/CS/HandBrakeWPF/Properties/Resources.resx
win/CS/HandBrakeWPF/Services/Scan/LibScan.cs
win/CS/HandBrakeWPF/UserSettingConstants.cs
win/CS/HandBrakeWPF/Utilities/BitmapHelpers.cs [new file with mode: 0644]
win/CS/HandBrakeWPF/Utilities/SystemInfo.cs
win/CS/HandBrakeWPF/ViewModels/Interfaces/IStaticPreviewViewModel.cs
win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
win/CS/HandBrakeWPF/ViewModels/StaticPreviewViewModel.cs
win/CS/HandBrakeWPF/ViewModels/SummaryViewModel.cs
win/CS/HandBrakeWPF/Views/StaticPreviewView.xaml
win/CS/HandBrakeWPF/Views/StaticPreviewView.xaml.cs
win/CS/HandBrakeWPF/defaultsettings.xml

index 56f0fc2dc5d29271effbc5b9fade0fbf2c73537b..fbb3669cabe22e05c47bd9de235e18761fda508b 100644 (file)
     <Compile Include="Services\UserSettingService.cs" />\r
     <Compile Include="Startup\StartupOptions.cs" />\r
     <Compile Include="Utilities\AppcastReader.cs" />\r
+    <Compile Include="Utilities\BitmapHelpers.cs" />\r
     <Compile Include="Utilities\BitmapUtilities.cs" />\r
     <Compile Include="Utilities\DelayedActionProcessor.cs" />\r
     <Compile Include="Utilities\DPIAwareness.cs" />\r
index 11cf168a3c1fdd7a029c0745c51cdc9bfbca1f12..915eb3eb44562226ede8b06fde2c18e624fc3c40 100644 (file)
@@ -4839,6 +4839,15 @@ namespace HandBrakeWPF.Properties {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Preview Rotation and Flip.
+        /// </summary>
+        public static string StaticPreviewView_PreviewRotationFlip {
+            get {
+                return ResourceManager.GetString("StaticPreviewView_PreviewRotationFlip", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Select a preview image.
         /// </summary>
index 2d0e235bf6e54203ed155b8ac949720d03ef7612..437efe84c0f4a54ee0abc6556c0e9f8385f06dc4 100644 (file)
@@ -2045,4 +2045,7 @@ Where supported, any user presets will have been imported.</value>
   <data name="MetadataView_TitleTag" xml:space="preserve">\r
     <value>Title:</value>\r
   </data>\r
+  <data name="StaticPreviewView_PreviewRotationFlip" xml:space="preserve">\r
+    <value>Preview Rotation and Flip</value>\r
+  </data>\r
 </root>
\ No newline at end of file
index d545ee2ed3ca57c9ea504f13af181f8ca6f4b779..e69f9aee4f0e697eb6ee4c30486a30b57d4be420 100644 (file)
@@ -217,7 +217,7 @@ namespace HandBrakeWPF.Services.Scan
                                                    PixelAspectY = job.PixelAspectY
                                                };
 
-                var bitmapData = this.instance.GetPreview(settings, preview, job.DeinterlaceFilter != DeinterlaceFilter.Off);
+                RawPreviewData bitmapData = this.instance.GetPreview(settings, preview, job.DeinterlaceFilter != DeinterlaceFilter.Off);
                 bitmapImage = BitmapUtilities.ConvertToBitmapImage(BitmapUtilities.ConvertByteArrayToBitmap(bitmapData));
             }
             catch (AccessViolationException e)
index c591443b50b351ef0db33fa175f13371a173f05b..92832a124dfa3c2f79f2fdc03b6aed4dcd70a191 100644 (file)
@@ -73,5 +73,6 @@ namespace HandBrakeWPF
         public const string AutonameFilePrePostString = "AutonameFilePrePostString";\r
         public const string WhenDonePerformActionImmediately = "WhenDonePerformActionImmediately";\r
         public const string UseDarkTheme = "UseDarkTheme";\r
+        public const string PreviewRotationFlip = "PreviewRotationFlip";\r
     }\r
 }
\ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Utilities/BitmapHelpers.cs b/win/CS/HandBrakeWPF/Utilities/BitmapHelpers.cs
new file mode 100644 (file)
index 0000000..f9856d2
--- /dev/null
@@ -0,0 +1,39 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="DelayedActionProcessor.cs" company="HandBrake Project (http://handbrake.fr)">
+//   This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+//   An Action processor that supports queueing/delayed action processing.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Utilities
+{
+    using System.Windows.Media;
+    using System.Windows.Media.Imaging;
+
+    public class BitmapHelpers
+    {
+        public static BitmapSource CreateTransformedBitmap(BitmapSource source, int rotation, bool flip)
+        {
+            if ((rotation == 0) && !flip)
+            {
+                return source;
+            }
+
+            TransformedBitmap transformedBitmap = new TransformedBitmap();
+            transformedBitmap.BeginInit();
+            transformedBitmap.Source = source;
+
+            var transformGroup = new TransformGroup();
+            transformGroup.Children.Add(new ScaleTransform(1, flip ? -1 : 1));
+            transformGroup.Children.Add(new RotateTransform(rotation));
+
+            transformedBitmap.Transform = transformGroup;
+            transformedBitmap.EndInit();
+            transformedBitmap.Freeze();
+
+            return (BitmapSource)transformedBitmap;
+        }
+    }
+}
index ca32b7af43e97369c3e7830d2ed0e9dfc60307a1..be7c1827bbcf0a61213c2fda513af7576b9c8b93 100644 (file)
@@ -82,6 +82,7 @@ namespace HandBrakeWPF.Utilities
 
                         foreach (PropertyData pc in share.Properties)
                         {
+                            Console.WriteLine(pc.Name + ": " + pc.Value);
                             if (!string.IsNullOrEmpty(pc.Name) && pc.Value != null)
                             {
                                 if (pc.Name.Equals("DriverVersion")) version = pc.Value.ToString();
index 0c1884bb11e8368ca97ed9f87bf47ba0331bb2ef..9605537c9d25acaaa92a7a172324c3e7d14650d1 100644 (file)
@@ -36,7 +36,7 @@ namespace HandBrakeWPF.ViewModels.Interfaces
         /// </summary>\r
         bool IsOpen { get; set; }\r
 \r
-        BitmapImage PreviewImage { get; }\r
+        BitmapSource PreviewImage { get; }\r
 \r
         void PreviousPreview();\r
         void NextPreview();\r
index 0cb68435e597d29d0744c2c699cd749776d5cb20..5114949c4409a73d6a4d4a72ddbad39950be3262 100644 (file)
@@ -253,7 +253,7 @@ namespace HandBrakeWPF.ViewModels
             get\r
             {\r
                 if (this.SelectedTask != null &&\r
-                    (this.selectedTask.Status == QueueItemStatus.Completed || this.selectedTask.Status == QueueItemStatus.Error))\r
+                    (this.selectedTask.Status == QueueItemStatus.Completed || this.selectedTask.Status == QueueItemStatus.Error || this.selectedTask.Status == QueueItemStatus.InProgress))\r
                 {\r
                     return true;\r
                 }\r
@@ -726,7 +726,6 @@ namespace HandBrakeWPF.ViewModels
                     if (directory != null && Directory.Exists(directory))\r
                     {\r
                         Process.Start(directory);\r
-\r
                     }\r
                 }\r
             }\r
index 72a36aa9a41d0e5d04f1d9df5898c87536d7e566..8608ea259e3936ae373ca5b625da883fe78c1564 100644 (file)
@@ -30,6 +30,7 @@ namespace HandBrakeWPF.ViewModels
     using HandBrakeWPF.Services.Queue.Model;\r
     using HandBrakeWPF.Services.Scan.Interfaces;\r
     using HandBrakeWPF.Services.Scan.Model;\r
+    using HandBrakeWPF.Utilities;\r
     using HandBrakeWPF.ViewModels.Interfaces;\r
 \r
     using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs;\r
@@ -45,79 +46,20 @@ namespace HandBrakeWPF.ViewModels
     /// </summary>\r
     public class StaticPreviewViewModel : ViewModelBase, IStaticPreviewViewModel\r
     {\r
-        /*\r
-         * TODO\r
-         * - Window Size / Scale to screen etc.\r
-         */\r
-\r
-        #region Fields\r
-\r
-        /// <summary>\r
-        ///     The scan service.\r
-        /// </summary>\r
         private readonly IScan scanService;\r
-\r
-        /// <summary>\r
-        /// Backing field for the encode service.\r
-        /// </summary>\r
         private readonly IEncode encodeService;\r
-\r
-        /// <summary>\r
-        /// The error service\r
-        /// </summary>\r
         private readonly IErrorService errorService;\r
-\r
-        /// <summary>\r
-        /// The user Setting Service\r
-        /// </summary>\r
         private readonly IUserSettingService userSettingService;\r
-\r
-        /// <summary>\r
-        ///     The height.\r
-        /// </summary>\r
         private int height;\r
-\r
-        /// <summary>\r
-        ///     The preview image.\r
-        /// </summary>\r
-        private BitmapImage previewImage;\r
-\r
-        /// <summary>\r
-        ///     The selected preview image.\r
-        /// </summary>\r
+        private BitmapSource previewImage;\r
         private int selectedPreviewImage;\r
-\r
-        /// <summary>\r
-        ///     The width.\r
-        /// </summary>\r
         private int width;\r
-\r
-        /// <summary>\r
-        /// The preview not available.\r
-        /// </summary>\r
         private bool previewNotAvailable;\r
-\r
-        /// <summary>\r
-        /// The percentage.\r
-        /// </summary>\r
         private string percentage;\r
-\r
-        /// <summary>\r
-        /// The percentage value.\r
-        /// </summary>\r
         private double percentageValue;\r
-\r
-        /// <summary>\r
-        /// The Backing field for IsEncoding\r
-        /// </summary>\r
         private bool isEncoding;\r
-\r
-        /// <summary>\r
-        /// Backing field for use system default player\r
-        /// </summary>\r
         private bool useSystemDefaultPlayer;\r
-\r
-        #endregion\r
+        private bool previewRotateFlip;\r
 \r
         #region Constructors and Destructors\r
 \r
@@ -141,6 +83,8 @@ namespace HandBrakeWPF.ViewModels
 \r
             this.useSystemDefaultPlayer = userSettingService.GetUserSetting<bool>(UserSettingConstants.DefaultPlayer);\r
             this.Duration = userSettingService.GetUserSetting<int>(UserSettingConstants.LastPreviewDuration);\r
+            this.previewRotateFlip = userSettingService.GetUserSetting<bool>(UserSettingConstants.PreviewRotationFlip);\r
+            this.NotifyOfPropertyChange(() => this.previewRotateFlip); // Don't want to trigger an Update, so setting the backing variable. \r
         }\r
 \r
         #endregion\r
@@ -170,7 +114,7 @@ namespace HandBrakeWPF.ViewModels
         /// <summary>\r
         ///     Gets or sets the preview image.\r
         /// </summary>\r
-        public BitmapImage PreviewImage\r
+        public BitmapSource PreviewImage\r
         {\r
             get\r
             {\r
@@ -210,6 +154,24 @@ namespace HandBrakeWPF.ViewModels
             }\r
         }\r
 \r
+        public bool PreviewRotateFlip\r
+        {\r
+            get => this.previewRotateFlip;\r
+            set\r
+            {\r
+                if (value == this.previewRotateFlip)\r
+                {\r
+                    return;\r
+                }\r
+\r
+                this.previewRotateFlip = value;\r
+                this.NotifyOfPropertyChange(() => this.PreviewRotateFlip);\r
+\r
+                this.UpdatePreviewFrame();\r
+                this.userSettingService.SetUserSetting(UserSettingConstants.PreviewRotationFlip, value);\r
+            }\r
+        }\r
+\r
         /// <summary>\r
         ///     Gets or sets the task.\r
         /// </summary>\r
@@ -455,7 +417,7 @@ namespace HandBrakeWPF.ViewModels
                 return;\r
             }\r
 \r
-            BitmapImage image = null;\r
+            BitmapSource image = null;\r
             try\r
             {\r
                 image = this.scanService.GetPreview(this.Task, this.SelectedPreviewImage, HBConfigurationFactory.Create());\r
@@ -468,6 +430,11 @@ namespace HandBrakeWPF.ViewModels
 \r
             if (image != null)\r
             {\r
+                if (previewRotateFlip)\r
+                {\r
+                    image = BitmapHelpers.CreateTransformedBitmap(image, this.Task.Rotation, this.Task.FlipVideo);\r
+                }\r
+\r
                 PreviewNotAvailable = false;\r
                 this.Width = (int)Math.Ceiling(image.Width);\r
                 this.Height = (int)Math.Ceiling(image.Height);\r
index 771fbec6e6c0edbc40123cc66a10d135c49ca4e6..aaf477e1bd2c0af17e0a2bc8fac5785946ada0be 100644 (file)
@@ -15,6 +15,7 @@ namespace HandBrakeWPF.ViewModels
     using System.IO;
     using System.Runtime.ExceptionServices;
     using System.Text;
+    using System.Windows.Media;
     using System.Windows.Media.Imaging;
 
     using HandBrake.Interop.Interop;
@@ -131,7 +132,7 @@ namespace HandBrakeWPF.ViewModels
 
         #region DisplayProperties
 
-        public BitmapImage PreviewImage { get; set; }
+        public BitmapSource PreviewImage { get; set; }
         public bool PreviewNotAvailable { get; set; }
         public int MaxWidth { get; set; }
         public int MaxHeight { get; set; }
@@ -668,7 +669,7 @@ namespace HandBrakeWPF.ViewModels
                 return;
             }
 
-            BitmapImage image = null;
+            BitmapSource image = null;
             try
             {
                 image = this.scanService.GetPreview(this.Task, this.selectedPreview - 1, HBConfigurationFactory.Create()); 
@@ -681,6 +682,8 @@ namespace HandBrakeWPF.ViewModels
 
             if (image != null)
             {
+                image = BitmapHelpers.CreateTransformedBitmap(image, this.task.Rotation, this.task.FlipVideo);
+
                 this.PreviewNotAvailable = false;
                 this.PreviewImage = image;
                 this.MaxWidth = (int)image.Width;
index 6f1b546940208a422ade1689e926fcf8e3bf3508..db622c247ca1a930036f73e72963cde3b1cc711d 100644 (file)
                     <RowDefinition Height="Auto" />\r
                     <RowDefinition Height="Auto" />\r
                     <RowDefinition Height="Auto" />\r
+                    <RowDefinition Height="Auto" />\r
                 </Grid.RowDefinitions>\r
+\r
                 <Slider Maximum="{Binding TotalPreviews}" Minimum="0" AutomationProperties.Name="{x:Static Properties:Resources.StaticPreviewView_SelectPreviewImage}"\r
                 Value="{Binding SelectedPreviewImage}"\r
                 VerticalAlignment="Center"\r
                 HorizontalAlignment="Stretch"\r
-                Background="Transparent" TickPlacement="TopLeft"\r
-                        Margin="0,0,0,5"\r
-                />\r
+                Background="Transparent" TickPlacement="TopLeft" Margin="0,0,0,5" />\r
+\r
+                <CheckBox IsChecked="{Binding PreviewRotateFlip}" Content="{x:Static Properties:Resources.StaticPreviewView_PreviewRotationFlip}" Foreground="White" Grid.Row="1" Margin="0,0,0,10" />\r
 \r
-                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Left">\r
+                <StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Left">\r
                     <Button Content="{x:Static Properties:Resources.StaticPreviewView_LivePreview}" Padding="8,2" cal:Message.Attach="[Event Click] = [Action Play]" />\r
                     <TextBlock Margin="10,0,5,0" VerticalAlignment="Center" Foreground="White" Text="{x:Static Properties:Resources.StaticPreviewView_Duration}" />\r
                     <ComboBox Width="60"\r
                     <CheckBox VerticalAlignment="Center" Content="{x:Static Properties:Resources.StaticPreviewView_UseSystemDefault}" Foreground="White" Margin="10,0,0,0" IsChecked="{Binding UseSystemDefaultPlayer}" />\r
                 </StackPanel>\r
 \r
-                <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,5,0,0">\r
-\r
-                </StackPanel>\r
-\r
-                <Grid  Margin="0,10,10,0" Grid.Row="2" Visibility="{Binding IsEncoding, Converter={StaticResource booleanToVisibilityConverter}}">\r
+                <Grid  Margin="0,10,10,0" Grid.Row="3" Visibility="{Binding IsEncoding, Converter={StaticResource booleanToVisibilityConverter}}">\r
                     <Grid.ColumnDefinitions>\r
                         <ColumnDefinition Width="23*" />\r
                         <ColumnDefinition Width="289*"/>\r
index 2289cfe45704e3a7f8005897f0b4b614b3b9b3a0..2a36e71afbc354016af845adda28b70753f9b41a 100644 (file)
@@ -64,7 +64,7 @@ namespace HandBrakeWPF.Views
 \r
         private void UpdateWindowTitle()\r
         {\r
-            BitmapImage image = ((IStaticPreviewViewModel)this.DataContext).PreviewImage;\r
+            BitmapSource image = ((IStaticPreviewViewModel)this.DataContext).PreviewImage;\r
             if (image != null && this.previewImage != null && this.previewImage.ActualWidth > 0)\r
             {\r
                 double origWidth = Math.Round(image.Width, 0);\r
index 04ce09cd5ceb77c66da2c11bb250ec016f70ef27..1efd1113a6fe6c93f6137c389fdbf6e55324b5c3 100644 (file)
       <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:boolean" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">false</anyType>\r
     </value>\r
   </item>\r
+  <item>\r
+    <key>\r
+      <string>PreviewRotationFlip</string>\r
+    </key>\r
+    <value>\r
+      <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:boolean" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">false</anyType>\r
+    </value>\r
+  </item>\r
 </dictionary>
\ No newline at end of file