@@ -22,10 +22,21 @@ public partial class PreviewWindow : Window
2222 {
2323 private PreviewViewModel viewModel ;
2424
25+ // DPI factors for the OS. Used to scale back down the images so they display at native resolution.
26+ // Normal DPI: 1.0
27+ // 120 DPI: 1.25
28+ // 144 DPI: 1.5
29+ private double dpiXFactor , dpiYFactor ;
30+
2531 public PreviewWindow ( )
2632 {
2733 InitializeComponent ( ) ;
2834
35+ // Get system DPI
36+ Matrix m = PresentationSource . FromVisual ( Application . Current . MainWindow ) . CompositionTarget . TransformToDevice ;
37+ this . dpiXFactor = m . M11 ;
38+ this . dpiYFactor = m . M22 ;
39+
2940 this . previewControls . Opacity = 0.0 ;
3041 this . DataContextChanged += new DependencyPropertyChangedEventHandler ( PreviewWindow_DataContextChanged ) ;
3142 }
@@ -60,6 +71,14 @@ protected override void OnSourceInitialized(EventArgs e)
6071 this . Left = workArea . Left + widthRemaining / 2 + 676 ;
6172 this . Top = workArea . Top + heightRemaining / 2 ;
6273 }
74+
75+ // Initialize window size to fit 853x480 at native resolution.
76+ double targetImageWidth = 480.0 * ( 16.0 / 9.0 ) ;
77+ double targetImageHeight = 480.0 ;
78+
79+ // Add some for the window borders and scale to DPI
80+ this . Width = ( targetImageWidth + 16.0 ) / this . dpiXFactor ;
81+ this . Height = ( targetImageHeight + 34.0 ) / this . dpiYFactor ;
6382 }
6483 else
6584 {
@@ -76,8 +95,12 @@ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs
7695 private void RefreshImageSize ( )
7796 {
7897 PreviewViewModel previewVM = this . DataContext as PreviewViewModel ;
79- double width = previewVM . PreviewWidth ;
80- double height = previewVM . PreviewHeight ;
98+ double widthPixels = previewVM . PreviewWidth ;
99+ double heightPixels = previewVM . PreviewHeight ;
100+
101+ // Convert pixels to WPF length units: we want to keep native image resolution.
102+ double width = widthPixels / this . dpiXFactor ;
103+ double height = heightPixels / this . dpiYFactor ;
81104
82105 double availableWidth = this . previewImageHolder . ActualWidth ;
83106 double availableHeight = this . previewImageHolder . ActualHeight ;
@@ -86,6 +109,15 @@ private void RefreshImageSize()
86109 {
87110 this . previewImage . Width = width ;
88111 this . previewImage . Height = height ;
112+
113+ double left = ( availableWidth - width ) / 2 ;
114+ double top = ( availableHeight - height ) / 2 ;
115+
116+ // Round to nearest pixel
117+ left = Math . Floor ( left * this . dpiXFactor ) / this . dpiXFactor ;
118+ top = Math . Floor ( top * this . dpiYFactor ) / this . dpiYFactor ;
119+
120+ this . previewImage . Margin = new Thickness ( left , top , 0 , 0 ) ;
89121 return ;
90122 }
91123
@@ -96,15 +128,31 @@ private void RefreshImageSize()
96128 {
97129 // If the image is shorter than the space available and is touching the sides
98130 double scalingFactor = availableWidth / width ;
131+ double resizedHeight = height * scalingFactor ;
99132 this . previewImage . Width = availableWidth ;
100- this . previewImage . Height = height * scalingFactor ;
133+ this . previewImage . Height = resizedHeight ;
134+
135+ double top = ( availableHeight - resizedHeight ) / 2 ;
136+
137+ // Round to nearest pixel
138+ top = Math . Floor ( top * this . dpiYFactor ) / this . dpiYFactor ;
139+
140+ this . previewImage . Margin = new Thickness ( 0 , top , 0 , 0 ) ;
101141 }
102142 else
103143 {
104144 // If the image is taller than the space available and is touching the top and bottom
105145 double scalingFactor = availableHeight / height ;
106- this . previewImage . Width = width * scalingFactor ;
146+ double resizedWidth = width * scalingFactor ;
147+ this . previewImage . Width = resizedWidth ;
107148 this . previewImage . Height = availableHeight ;
149+
150+ double left = ( availableWidth - resizedWidth ) / 2 ;
151+
152+ // Round to nearest pixel
153+ left = Math . Floor ( left * this . dpiXFactor ) / this . dpiXFactor ;
154+
155+ this . previewImage . Margin = new Thickness ( left , 0 , 0 , 0 ) ;
108156 }
109157 }
110158
0 commit comments