From d8372568e08f9802dd8f3d42591c32a6474299ca Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 4 Feb 2022 00:45:50 +1100 Subject: [PATCH] Convert OrientationMode into something usable. --- .../Exif/Values/ExifOrientationMode.cs} | 24 +++---- .../Linear/AutoOrientProcessor{TPixel}.cs | 36 +++++----- .../Processors/Transforms/AutoOrientTests.cs | 71 +++++++++---------- 3 files changed, 64 insertions(+), 67 deletions(-) rename src/ImageSharp/{Processing/OrientationMode.cs => Metadata/Profiles/Exif/Values/ExifOrientationMode.cs} (69%) diff --git a/src/ImageSharp/Processing/OrientationMode.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifOrientationMode.cs similarity index 69% rename from src/ImageSharp/Processing/OrientationMode.cs rename to src/ImageSharp/Metadata/Profiles/Exif/Values/ExifOrientationMode.cs index a8ba5a55c..b68390ae0 100644 --- a/src/ImageSharp/Processing/OrientationMode.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifOrientationMode.cs @@ -1,56 +1,56 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -namespace SixLabors.ImageSharp.Processing +namespace SixLabors.ImageSharp.Metadata.Profiles.Exif { /// /// Enumerates the available orientation values supplied by EXIF metadata. /// - internal enum OrientationMode : ushort + public static class ExifOrientationMode { /// /// Unknown rotation. /// - Unknown = 0, + public const ushort Unknown = 0; /// /// The 0th row at the top, the 0th column on the left. /// - TopLeft = 1, + public const ushort TopLeft = 1; /// /// The 0th row at the top, the 0th column on the right. /// - TopRight = 2, + public const ushort TopRight = 2; /// /// The 0th row at the bottom, the 0th column on the right. /// - BottomRight = 3, + public const ushort BottomRight = 3; /// /// The 0th row at the bottom, the 0th column on the left. /// - BottomLeft = 4, + public const ushort BottomLeft = 4; /// /// The 0th row on the left, the 0th column at the top. /// - LeftTop = 5, + public const ushort LeftTop = 5; /// /// The 0th row at the right, the 0th column at the top. /// - RightTop = 6, + public const ushort RightTop = 6; /// /// The 0th row on the right, the 0th column at the bottom. /// - RightBottom = 7, + public const ushort RightBottom = 7; /// /// The 0th row on the left, the 0th column at the bottom. /// - LeftBottom = 8 + public const ushort LeftBottom = 8; } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs index 6c5219b3a..c9f9d4327 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs @@ -28,42 +28,42 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// protected override void BeforeImageApply() { - OrientationMode orientation = GetExifOrientation(this.Source); + ushort orientation = GetExifOrientation(this.Source); Size size = this.SourceRectangle.Size; switch (orientation) { - case OrientationMode.TopRight: + case ExifOrientationMode.TopRight: new FlipProcessor(FlipMode.Horizontal).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.BottomRight: + case ExifOrientationMode.BottomRight: new RotateProcessor((int)RotateMode.Rotate180, size).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.BottomLeft: + case ExifOrientationMode.BottomLeft: new FlipProcessor(FlipMode.Vertical).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.LeftTop: + case ExifOrientationMode.LeftTop: new RotateProcessor((int)RotateMode.Rotate90, size).Execute(this.Configuration, this.Source, this.SourceRectangle); new FlipProcessor(FlipMode.Horizontal).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.RightTop: + case ExifOrientationMode.RightTop: new RotateProcessor((int)RotateMode.Rotate90, size).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.RightBottom: + case ExifOrientationMode.RightBottom: new FlipProcessor(FlipMode.Vertical).Execute(this.Configuration, this.Source, this.SourceRectangle); new RotateProcessor((int)RotateMode.Rotate270, size).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.LeftBottom: + case ExifOrientationMode.LeftBottom: new RotateProcessor((int)RotateMode.Rotate270, size).Execute(this.Configuration, this.Source, this.SourceRectangle); break; - case OrientationMode.Unknown: - case OrientationMode.TopLeft: + case ExifOrientationMode.Unknown: + case ExifOrientationMode.TopLeft: default: break; } @@ -81,32 +81,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// Returns the current EXIF orientation /// /// The image to auto rotate. - /// The - private static OrientationMode GetExifOrientation(Image source) + /// The + private static ushort GetExifOrientation(Image source) { if (source.Metadata.ExifProfile is null) { - return OrientationMode.Unknown; + return ExifOrientationMode.Unknown; } IExifValue value = source.Metadata.ExifProfile.GetValue(ExifTag.Orientation); if (value is null) { - return OrientationMode.Unknown; + return ExifOrientationMode.Unknown; } - OrientationMode orientation; + ushort orientation; if (value.DataType == ExifDataType.Short) { - orientation = (OrientationMode)value.Value; + orientation = value.Value; } else { - orientation = (OrientationMode)Convert.ToUInt16(value.Value); + orientation = Convert.ToUInt16(value.Value); source.Metadata.ExifProfile.RemoveValue(ExifTag.Orientation); } - source.Metadata.ExifProfile.SetValue(ExifTag.Orientation, (ushort)OrientationMode.TopLeft); + source.Metadata.ExifProfile.SetValue(ExifTag.Orientation, ExifOrientationMode.TopLeft); return orientation; } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs index 38fde5060..597c02dfc 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs @@ -18,42 +18,41 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public const string FlipTestFile = TestImages.Bmp.F; public static readonly TheoryData InvalidOrientationValues - = new TheoryData - { - { ExifDataType.Byte, new byte[] { 1 } }, - { ExifDataType.SignedByte, new byte[] { 2 } }, - { ExifDataType.SignedShort, BitConverter.GetBytes((short)3) }, - { ExifDataType.Long, BitConverter.GetBytes(4U) }, - { ExifDataType.SignedLong, BitConverter.GetBytes(5) } - }; + = new() + { + { ExifDataType.Byte, new byte[] { 1 } }, + { ExifDataType.SignedByte, new byte[] { 2 } }, + { ExifDataType.SignedShort, BitConverter.GetBytes((short)3) }, + { ExifDataType.Long, BitConverter.GetBytes(4U) }, + { ExifDataType.SignedLong, BitConverter.GetBytes(5) } + }; - public static readonly TheoryData ExifOrientationValues = new TheoryData - { - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8 - }; + public static readonly TheoryData ExifOrientationValues + = new() + { + ExifOrientationMode.Unknown, + ExifOrientationMode.TopLeft, + ExifOrientationMode.TopRight, + ExifOrientationMode.BottomRight, + ExifOrientationMode.BottomLeft, + ExifOrientationMode.LeftTop, + ExifOrientationMode.RightTop, + ExifOrientationMode.RightBottom, + ExifOrientationMode.LeftBottom + }; [Theory] [WithFile(FlipTestFile, nameof(ExifOrientationValues), PixelTypes.Rgba32)] public void AutoOrient_WorksForAllExifOrientations(TestImageProvider provider, ushort orientation) where TPixel : unmanaged, IPixel { - using (Image image = provider.GetImage()) - { - image.Metadata.ExifProfile = new ExifProfile(); - image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, orientation); + using Image image = provider.GetImage(); + image.Metadata.ExifProfile = new ExifProfile(); + image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, orientation); - image.Mutate(x => x.AutoOrient()); - image.DebugSave(provider, orientation, appendPixelTypeToFileName: false); - image.CompareToReferenceOutput(provider, orientation, appendPixelTypeToFileName: false); - } + image.Mutate(x => x.AutoOrient()); + image.DebugSave(provider, orientation, appendPixelTypeToFileName: false); + image.CompareToReferenceOutput(provider, orientation, appendPixelTypeToFileName: false); } [Theory] @@ -76,19 +75,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms // Change the number of components bytes[20] = 1; - var orientationCodeData = new byte[8]; + byte[] orientationCodeData = new byte[8]; Array.Copy(orientation, orientationCodeData, orientation.Length); ulong orientationCode = BitConverter.ToUInt64(orientationCodeData, 0); - using (Image image = provider.GetImage()) - using (Image reference = image.Clone()) - { - image.Metadata.ExifProfile = new ExifProfile(bytes); - image.Mutate(x => x.AutoOrient()); - image.DebugSave(provider, $"{dataType}-{orientationCode}", appendPixelTypeToFileName: false); - ImageComparer.Exact.VerifySimilarity(image, reference); - } + using Image image = provider.GetImage(); + using Image reference = image.Clone(); + image.Metadata.ExifProfile = new ExifProfile(bytes); + image.Mutate(x => x.AutoOrient()); + image.DebugSave(provider, $"{dataType}-{orientationCode}", appendPixelTypeToFileName: false); + ImageComparer.Exact.VerifySimilarity(image, reference); } } }