Skip to content

Commit 89f1bb4

Browse files
committed
Fix #337: Exif rotation is broken in WPF
1 parent a34bacb commit 89f1bb4

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/NativeImageProvider.cs

+63-8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public override Task<BitmapSource> GetThumbnail(Size size, Size fullSize)
4040
Math.Min(size.Width / 2 / fullSize.Width,
4141
size.Height / 2 / fullSize.Height));
4242
var decodeHeight = (int) Math.Round(fullSize.Height / fullSize.Width * decodeWidth);
43+
var orientation = Meta.GetOrientation();
44+
var rotate = ShouldRotate(orientation);
4345

4446
return new Task<BitmapSource>(() =>
4547
{
@@ -49,14 +51,19 @@ public override Task<BitmapSource> GetThumbnail(Size size, Size fullSize)
4951
img.BeginInit();
5052
img.UriSource = new Uri(Path);
5153
img.CacheOption = BitmapCacheOption.OnLoad;
52-
img.DecodePixelWidth = decodeWidth;
53-
img.DecodePixelHeight = decodeHeight; // specific size to avoid .net's double to int conversion
54+
img.DecodePixelWidth = rotate ? decodeHeight : decodeWidth;
55+
img.DecodePixelHeight = rotate ? decodeWidth : decodeHeight; // specific size to avoid .net's double to int conversion
5456
img.EndInit();
5557

56-
var scaled = new TransformedBitmap(img,
57-
new ScaleTransform(fullSize.Width / img.PixelWidth, fullSize.Height / img.PixelHeight));
58-
scaled.Freeze();
59-
return scaled;
58+
var scaled = rotate ?
59+
new TransformedBitmap(img,
60+
new ScaleTransform(fullSize.Height / img.PixelWidth, fullSize.Width / img.PixelHeight))
61+
: new TransformedBitmap(img,
62+
new ScaleTransform(fullSize.Width / img.PixelWidth, fullSize.Height / img.PixelHeight));
63+
64+
var rotated = ApplyTransformFromExif(scaled, orientation);
65+
rotated.Freeze();
66+
return rotated;
6067
}
6168
catch (Exception e)
6269
{
@@ -78,8 +85,10 @@ public override Task<BitmapSource> GetRenderedFrame(int index)
7885
img.CacheOption = BitmapCacheOption.OnLoad;
7986
img.EndInit();
8087

81-
img.Freeze();
82-
return img;
88+
var img2 = ApplyTransformFromExif(img, Meta.GetOrientation());
89+
img2.Freeze();
90+
91+
return img2;
8392
}
8493
catch (Exception e)
8594
{
@@ -89,6 +98,52 @@ public override Task<BitmapSource> GetRenderedFrame(int index)
8998
});
9099
}
91100

101+
private static bool ShouldRotate(Orientation orientation)
102+
{
103+
bool rotate = false;
104+
switch (orientation)
105+
{
106+
case Orientation.LeftTop:
107+
case Orientation.RightTop:
108+
case Orientation.RightBottom:
109+
case Orientation.Leftbottom:
110+
rotate = true;
111+
break;
112+
}
113+
114+
return rotate;
115+
}
116+
117+
private static BitmapSource ApplyTransformFromExif(BitmapSource image, Orientation orientation)
118+
{
119+
switch (orientation)
120+
{
121+
case Orientation.Undefined:
122+
case Orientation.TopLeft:
123+
return image;
124+
case Orientation.TopRight:
125+
return new TransformedBitmap(image, new ScaleTransform(-1, 1, 0, 0));
126+
case Orientation.BottomRight:
127+
return new TransformedBitmap(image, new RotateTransform(180));
128+
case Orientation.BottomLeft:
129+
return new TransformedBitmap(image, new ScaleTransform(1, 1, 0, 0));
130+
case Orientation.LeftTop:
131+
return new TransformedBitmap(
132+
new TransformedBitmap(image, new RotateTransform(90)),
133+
new ScaleTransform(-1, 1, 0, 0));
134+
case Orientation.RightTop:
135+
return new TransformedBitmap(image, new RotateTransform(90));
136+
case Orientation.RightBottom:
137+
return new TransformedBitmap(
138+
new TransformedBitmap(image, new RotateTransform(270)),
139+
new ScaleTransform(-1, 1, 0, 0));
140+
case Orientation.Leftbottom:
141+
return new TransformedBitmap(image, new RotateTransform(270));
142+
}
143+
144+
return image;
145+
}
146+
92147
public override void Dispose()
93148
{
94149
}

0 commit comments

Comments
 (0)