Skip to content

Commit ade3f94

Browse files
Merge pull request #242 from ronaldbarendse/js/helpers
Fix anchor position transforms and tests in ExifOrientationUtilities
2 parents 1a7a815 + ee782ac commit ade3f94

3 files changed

Lines changed: 165 additions & 107 deletions

File tree

src/ImageSharp.Web/ExifOrientationUtilities.cs

Lines changed: 116 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Numerics;
56
using System.Runtime.CompilerServices;
67
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
@@ -25,8 +26,9 @@ public static class ExifOrientationUtilities
2526
/// </returns>
2627
public static Vector2 Transform(Vector2 position, Vector2 min, Vector2 max, ushort orientation)
2728
{
28-
if (orientation is >= ExifOrientationMode.Unknown and <= ExifOrientationMode.TopLeft)
29+
if (orientation is <= ExifOrientationMode.TopLeft or > ExifOrientationMode.LeftBottom)
2930
{
31+
// Short circuit orientations that are not transformed below
3032
return position;
3133
}
3234

@@ -62,7 +64,7 @@ public static Vector2 Transform(Vector2 position, Vector2 min, Vector2 max, usho
6264
builder.AppendRotationDegrees(90);
6365
break;
6466
default:
65-
return position;
67+
break;
6668
}
6769

6870
Matrix3x2 matrix = builder.BuildMatrix(size);
@@ -91,93 +93,119 @@ public static Size Transform(Size size, ushort orientation)
9193
/// The transformed anchor.
9294
/// </returns>
9395
public static AnchorPositionMode Transform(AnchorPositionMode anchor, ushort orientation)
94-
{
95-
if (orientation is >= ExifOrientationMode.Unknown and <= ExifOrientationMode.TopLeft)
96-
{
97-
return anchor;
98-
}
99-
100-
/*
101-
New anchor position is determined by calculating the direction of the anchor relative to the source image.
102-
In the following example, the TopRight anchor becomes BottomRight
103-
104-
T L
105-
+-----------------------+ +--------------+
106-
| *| | |
107-
| | | |
108-
L | TL | R | |
109-
| | | |
110-
| | B | LB | T
111-
| | | |
112-
+-----------------------+ | |
113-
B | |
114-
| |
115-
| *|
116-
+--------------+
117-
R
96+
/*
97+
New anchor position is determined by calculating the direction of the anchor relative to the source image.
98+
In the following example, the TopRight anchor becomes BottomRight
99+
T L
100+
+-----------------------+ +--------------+
101+
| *| | |
102+
| | | |
103+
L | TL | R | |
104+
| | | |
105+
| | B | LB | T
106+
| | | |
107+
+-----------------------+ | |
108+
B | |
109+
| |
110+
| *|
111+
+--------------+
112+
R
118113
*/
119-
return anchor switch
120-
{
121-
AnchorPositionMode.Center => anchor,
122-
AnchorPositionMode.Top => orientation switch
123-
{
124-
ExifOrientationMode.BottomLeft or ExifOrientationMode.BottomRight => AnchorPositionMode.Bottom,
125-
ExifOrientationMode.LeftTop or ExifOrientationMode.RightTop => AnchorPositionMode.Left,
126-
ExifOrientationMode.LeftBottom or ExifOrientationMode.RightBottom => AnchorPositionMode.Right,
127-
_ => anchor,
128-
},
129-
AnchorPositionMode.Bottom => orientation switch
130-
{
131-
ExifOrientationMode.BottomLeft or ExifOrientationMode.BottomRight => AnchorPositionMode.Top,
132-
ExifOrientationMode.LeftTop or ExifOrientationMode.RightTop => AnchorPositionMode.Right,
133-
ExifOrientationMode.LeftBottom or ExifOrientationMode.RightBottom => AnchorPositionMode.Left,
134-
_ => anchor,
135-
},
136-
AnchorPositionMode.Left => orientation switch
137-
{
138-
ExifOrientationMode.TopRight or ExifOrientationMode.BottomRight => AnchorPositionMode.Right,
139-
ExifOrientationMode.LeftTop or ExifOrientationMode.LeftBottom => AnchorPositionMode.Top,
140-
ExifOrientationMode.RightTop or ExifOrientationMode.RightBottom => AnchorPositionMode.Bottom,
141-
_ => anchor,
142-
},
143-
AnchorPositionMode.Right => orientation switch
144-
{
145-
ExifOrientationMode.TopRight or ExifOrientationMode.BottomRight => AnchorPositionMode.Left,
146-
ExifOrientationMode.LeftTop or ExifOrientationMode.LeftBottom => AnchorPositionMode.Bottom,
147-
ExifOrientationMode.RightTop or ExifOrientationMode.RightBottom => AnchorPositionMode.Top,
148-
_ => anchor,
149-
},
150-
AnchorPositionMode.TopLeft => orientation switch
151-
{
152-
ExifOrientationMode.TopRight or ExifOrientationMode.LeftBottom => AnchorPositionMode.TopRight,
153-
ExifOrientationMode.BottomRight or ExifOrientationMode.RightTop => AnchorPositionMode.BottomLeft,
154-
ExifOrientationMode.BottomLeft or ExifOrientationMode.RightBottom => AnchorPositionMode.BottomRight,
155-
_ => anchor,
156-
},
157-
AnchorPositionMode.TopRight => orientation switch
158-
{
159-
ExifOrientationMode.TopRight or ExifOrientationMode.RightTop => AnchorPositionMode.TopLeft,
160-
ExifOrientationMode.BottomLeft or ExifOrientationMode.LeftBottom => AnchorPositionMode.BottomRight,
161-
ExifOrientationMode.BottomRight or ExifOrientationMode.LeftTop => AnchorPositionMode.BottomLeft,
162-
_ => anchor,
163-
},
164-
AnchorPositionMode.BottomRight => orientation switch
165-
{
166-
ExifOrientationMode.TopRight or ExifOrientationMode.LeftBottom => AnchorPositionMode.BottomLeft,
167-
ExifOrientationMode.BottomLeft or ExifOrientationMode.RightTop => AnchorPositionMode.TopRight,
168-
ExifOrientationMode.BottomRight or ExifOrientationMode.RightBottom => AnchorPositionMode.TopLeft,
169-
_ => anchor,
170-
},
171-
AnchorPositionMode.BottomLeft => orientation switch
172-
{
173-
ExifOrientationMode.TopRight or ExifOrientationMode.RightTop => AnchorPositionMode.BottomRight,
174-
ExifOrientationMode.BottomLeft or ExifOrientationMode.LeftBottom => AnchorPositionMode.TopLeft,
175-
ExifOrientationMode.BottomRight or ExifOrientationMode.LeftTop => AnchorPositionMode.TopRight,
176-
_ => anchor,
177-
},
178-
_ => anchor,
179-
};
180-
}
114+
=> orientation switch
115+
{
116+
ExifOrientationMode.TopRight => anchor switch
117+
{
118+
AnchorPositionMode.Center => AnchorPositionMode.Center,
119+
AnchorPositionMode.Top => AnchorPositionMode.Top,
120+
AnchorPositionMode.Bottom => AnchorPositionMode.Bottom,
121+
AnchorPositionMode.Left => AnchorPositionMode.Right,
122+
AnchorPositionMode.Right => AnchorPositionMode.Left,
123+
AnchorPositionMode.TopLeft => AnchorPositionMode.TopRight,
124+
AnchorPositionMode.TopRight => AnchorPositionMode.TopLeft,
125+
AnchorPositionMode.BottomRight => AnchorPositionMode.BottomLeft,
126+
AnchorPositionMode.BottomLeft => AnchorPositionMode.BottomRight,
127+
_ => anchor
128+
},
129+
ExifOrientationMode.BottomRight => anchor switch
130+
{
131+
AnchorPositionMode.Center => AnchorPositionMode.Center,
132+
AnchorPositionMode.Top => AnchorPositionMode.Bottom,
133+
AnchorPositionMode.Bottom => AnchorPositionMode.Top,
134+
AnchorPositionMode.Left => AnchorPositionMode.Right,
135+
AnchorPositionMode.Right => AnchorPositionMode.Left,
136+
AnchorPositionMode.TopLeft => AnchorPositionMode.BottomRight,
137+
AnchorPositionMode.TopRight => AnchorPositionMode.BottomLeft,
138+
AnchorPositionMode.BottomRight => AnchorPositionMode.TopLeft,
139+
AnchorPositionMode.BottomLeft => AnchorPositionMode.TopRight,
140+
_ => anchor
141+
},
142+
ExifOrientationMode.BottomLeft => anchor switch
143+
{
144+
AnchorPositionMode.Center => AnchorPositionMode.Center,
145+
AnchorPositionMode.Top => AnchorPositionMode.Bottom,
146+
AnchorPositionMode.Bottom => AnchorPositionMode.Top,
147+
AnchorPositionMode.Left => AnchorPositionMode.Left,
148+
AnchorPositionMode.Right => AnchorPositionMode.Right,
149+
AnchorPositionMode.TopLeft => AnchorPositionMode.BottomLeft,
150+
AnchorPositionMode.TopRight => AnchorPositionMode.BottomRight,
151+
AnchorPositionMode.BottomRight => AnchorPositionMode.TopRight,
152+
AnchorPositionMode.BottomLeft => AnchorPositionMode.TopLeft,
153+
_ => anchor
154+
},
155+
ExifOrientationMode.LeftTop => anchor switch
156+
{
157+
AnchorPositionMode.Center => AnchorPositionMode.Center,
158+
AnchorPositionMode.Top => AnchorPositionMode.Left,
159+
AnchorPositionMode.Bottom => AnchorPositionMode.Right,
160+
AnchorPositionMode.Left => AnchorPositionMode.Top,
161+
AnchorPositionMode.Right => AnchorPositionMode.Bottom,
162+
AnchorPositionMode.TopLeft => AnchorPositionMode.TopLeft,
163+
AnchorPositionMode.TopRight => AnchorPositionMode.BottomLeft,
164+
AnchorPositionMode.BottomRight => AnchorPositionMode.BottomRight,
165+
AnchorPositionMode.BottomLeft => AnchorPositionMode.TopRight,
166+
_ => anchor
167+
},
168+
ExifOrientationMode.RightTop => anchor switch
169+
{
170+
AnchorPositionMode.Center => AnchorPositionMode.Center,
171+
AnchorPositionMode.Top => AnchorPositionMode.Left,
172+
AnchorPositionMode.Bottom => AnchorPositionMode.Right,
173+
AnchorPositionMode.Left => AnchorPositionMode.Bottom,
174+
AnchorPositionMode.Right => AnchorPositionMode.Top,
175+
AnchorPositionMode.TopLeft => AnchorPositionMode.BottomLeft,
176+
AnchorPositionMode.TopRight => AnchorPositionMode.TopLeft,
177+
AnchorPositionMode.BottomRight => AnchorPositionMode.TopRight,
178+
AnchorPositionMode.BottomLeft => AnchorPositionMode.BottomRight,
179+
_ => anchor
180+
},
181+
ExifOrientationMode.RightBottom => anchor switch
182+
{
183+
AnchorPositionMode.Center => AnchorPositionMode.Center,
184+
AnchorPositionMode.Top => AnchorPositionMode.Right,
185+
AnchorPositionMode.Bottom => AnchorPositionMode.Left,
186+
AnchorPositionMode.Left => AnchorPositionMode.Bottom,
187+
AnchorPositionMode.Right => AnchorPositionMode.Top,
188+
AnchorPositionMode.TopLeft => AnchorPositionMode.BottomRight,
189+
AnchorPositionMode.TopRight => AnchorPositionMode.TopRight,
190+
AnchorPositionMode.BottomRight => AnchorPositionMode.TopLeft,
191+
AnchorPositionMode.BottomLeft => AnchorPositionMode.BottomLeft,
192+
_ => anchor
193+
},
194+
ExifOrientationMode.LeftBottom => anchor switch
195+
{
196+
AnchorPositionMode.Center => AnchorPositionMode.Center,
197+
AnchorPositionMode.Top => AnchorPositionMode.Right,
198+
AnchorPositionMode.Bottom => AnchorPositionMode.Left,
199+
AnchorPositionMode.Left => AnchorPositionMode.Top,
200+
AnchorPositionMode.Right => AnchorPositionMode.Bottom,
201+
AnchorPositionMode.TopLeft => AnchorPositionMode.TopRight,
202+
AnchorPositionMode.TopRight => AnchorPositionMode.BottomRight,
203+
AnchorPositionMode.BottomRight => AnchorPositionMode.BottomLeft,
204+
AnchorPositionMode.BottomLeft => AnchorPositionMode.TopLeft,
205+
_ => anchor
206+
},
207+
_ => anchor
208+
};
181209

182210
/// <summary>
183211
/// Returns a value indicating whether an EXIF orientation is rotated (not flipped).

0 commit comments

Comments
 (0)