Fix #337: Exif rotation is broken in WPF

This commit is contained in:
Paddy Xu
2018-09-04 21:21:49 +03:00
parent a34bacb8f5
commit 89f1bb46b6

View File

@@ -40,6 +40,8 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
Math.Min(size.Width / 2 / fullSize.Width, Math.Min(size.Width / 2 / fullSize.Width,
size.Height / 2 / fullSize.Height)); size.Height / 2 / fullSize.Height));
var decodeHeight = (int) Math.Round(fullSize.Height / fullSize.Width * decodeWidth); var decodeHeight = (int) Math.Round(fullSize.Height / fullSize.Width * decodeWidth);
var orientation = Meta.GetOrientation();
var rotate = ShouldRotate(orientation);
return new Task<BitmapSource>(() => return new Task<BitmapSource>(() =>
{ {
@@ -49,14 +51,19 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
img.BeginInit(); img.BeginInit();
img.UriSource = new Uri(Path); img.UriSource = new Uri(Path);
img.CacheOption = BitmapCacheOption.OnLoad; img.CacheOption = BitmapCacheOption.OnLoad;
img.DecodePixelWidth = decodeWidth; img.DecodePixelWidth = rotate ? decodeHeight : decodeWidth;
img.DecodePixelHeight = decodeHeight; // specific size to avoid .net's double to int conversion img.DecodePixelHeight = rotate ? decodeWidth : decodeHeight; // specific size to avoid .net's double to int conversion
img.EndInit(); img.EndInit();
var scaled = new TransformedBitmap(img, var scaled = rotate ?
new TransformedBitmap(img,
new ScaleTransform(fullSize.Height / img.PixelWidth, fullSize.Width / img.PixelHeight))
: new TransformedBitmap(img,
new ScaleTransform(fullSize.Width / img.PixelWidth, fullSize.Height / img.PixelHeight)); new ScaleTransform(fullSize.Width / img.PixelWidth, fullSize.Height / img.PixelHeight));
scaled.Freeze();
return scaled; var rotated = ApplyTransformFromExif(scaled, orientation);
rotated.Freeze();
return rotated;
} }
catch (Exception e) catch (Exception e)
{ {
@@ -78,8 +85,10 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
img.CacheOption = BitmapCacheOption.OnLoad; img.CacheOption = BitmapCacheOption.OnLoad;
img.EndInit(); img.EndInit();
img.Freeze(); var img2 = ApplyTransformFromExif(img, Meta.GetOrientation());
return img; img2.Freeze();
return img2;
} }
catch (Exception e) catch (Exception e)
{ {
@@ -89,6 +98,52 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
}); });
} }
private static bool ShouldRotate(Orientation orientation)
{
bool rotate = false;
switch (orientation)
{
case Orientation.LeftTop:
case Orientation.RightTop:
case Orientation.RightBottom:
case Orientation.Leftbottom:
rotate = true;
break;
}
return rotate;
}
private static BitmapSource ApplyTransformFromExif(BitmapSource image, Orientation orientation)
{
switch (orientation)
{
case Orientation.Undefined:
case Orientation.TopLeft:
return image;
case Orientation.TopRight:
return new TransformedBitmap(image, new ScaleTransform(-1, 1, 0, 0));
case Orientation.BottomRight:
return new TransformedBitmap(image, new RotateTransform(180));
case Orientation.BottomLeft:
return new TransformedBitmap(image, new ScaleTransform(1, 1, 0, 0));
case Orientation.LeftTop:
return new TransformedBitmap(
new TransformedBitmap(image, new RotateTransform(90)),
new ScaleTransform(-1, 1, 0, 0));
case Orientation.RightTop:
return new TransformedBitmap(image, new RotateTransform(90));
case Orientation.RightBottom:
return new TransformedBitmap(
new TransformedBitmap(image, new RotateTransform(270)),
new ScaleTransform(-1, 1, 0, 0));
case Orientation.Leftbottom:
return new TransformedBitmap(image, new RotateTransform(270));
}
return image;
}
public override void Dispose() public override void Dispose()
{ {
} }