33
44using System . Collections . Generic ;
55using System . Globalization ;
6+ using System . Numerics ;
67using Microsoft . Extensions . Logging ;
78using SixLabors . ImageSharp . Metadata . Profiles . Exif ;
89using SixLabors . ImageSharp . Processing ;
@@ -123,7 +124,7 @@ internal static ResizeOptions GetResizeOptions(
123124 ResizeOptions options = new ( )
124125 {
125126 Size = size ,
126- CenterCoordinates = GetCenter ( rotated , commands , parser , culture ) ,
127+ CenterCoordinates = GetCenter ( image , orientation , commands , parser , culture ) ,
127128 Position = GetAnchor ( orientation , commands , parser , culture ) ,
128129 Mode = GetMode ( commands , parser , culture ) ,
129130 Compand = GetCompandMode ( commands , parser , culture ) ,
@@ -148,7 +149,8 @@ private static Size ParseSize(
148149 }
149150
150151 private static PointF ? GetCenter (
151- bool rotated ,
152+ FormattedImage image ,
153+ ushort orientation ,
152154 CommandCollection commands ,
153155 CommandParser parser ,
154156 CultureInfo culture )
@@ -160,7 +162,48 @@ private static Size ParseSize(
160162 return null ;
161163 }
162164
163- return rotated ? new PointF ( coordinates [ 1 ] , coordinates [ 0 ] ) : new PointF ( coordinates [ 0 ] , coordinates [ 1 ] ) ;
165+ PointF center = new ( coordinates [ 0 ] , coordinates [ 1 ] ) ;
166+ if ( orientation is >= ExifOrientationMode . Unknown and <= ExifOrientationMode . TopLeft )
167+ {
168+ return center ;
169+ }
170+
171+ AffineTransformBuilder builder = new ( ) ;
172+ Size size = image . Image . Size ( ) ;
173+
174+ // New XY is calculated based on flipping and rotating the input XY.
175+ // Operations are based upon AutoOrientProcessor implementation.
176+ switch ( orientation )
177+ {
178+ case ExifOrientationMode . TopRight :
179+ builder . AppendTranslation ( new PointF ( size . Width - center . X , 0 ) ) ;
180+ break ;
181+ case ExifOrientationMode . BottomRight :
182+ builder . AppendRotationDegrees ( 180 ) ;
183+ break ;
184+ case ExifOrientationMode . BottomLeft :
185+ builder . AppendTranslation ( new PointF ( 0 , size . Height - center . Y ) ) ;
186+ break ;
187+ case ExifOrientationMode . LeftTop :
188+ builder . AppendRotationDegrees ( 90 ) ;
189+ builder . AppendTranslation ( new PointF ( size . Width - center . X , 0 ) ) ;
190+ break ;
191+ case ExifOrientationMode . RightTop :
192+ builder . AppendRotationDegrees ( 90 ) ;
193+ break ;
194+ case ExifOrientationMode . RightBottom :
195+ builder . AppendTranslation ( new PointF ( 0 , size . Height - center . Y ) ) ;
196+ builder . AppendRotationDegrees ( 270 ) ;
197+ break ;
198+ case ExifOrientationMode . LeftBottom :
199+ builder . AppendRotationDegrees ( 270 ) ;
200+ break ;
201+ default :
202+ return center ;
203+ }
204+
205+ Matrix3x2 matrix = builder . BuildMatrix ( size ) ;
206+ return Vector2 . Transform ( center , matrix ) ;
164207 }
165208
166209 private static ResizeMode GetMode (
@@ -181,6 +224,25 @@ private static AnchorPositionMode GetAnchor(
181224 return anchor ;
182225 }
183226
227+ /*
228+ New anchor position is determined by calculating the direction of the anchor relative to the source image.
229+ In the following example, the TopRight anchor becomes BottomRight
230+
231+ T L
232+ +-----------------------+ +--------------+
233+ | *| | |
234+ | | | |
235+ L | TL | R | |
236+ | | | |
237+ | | B | LB | T
238+ | | | |
239+ +-----------------------+ | |
240+ B | |
241+ | |
242+ | *|
243+ +--------------+
244+ R
245+ */
184246 return anchor switch
185247 {
186248 AnchorPositionMode . Center => anchor ,
@@ -200,44 +262,44 @@ private static AnchorPositionMode GetAnchor(
200262 } ,
201263 AnchorPositionMode . Left => orientation switch
202264 {
203- ExifOrientationMode . TopRight or ExifOrientationMode . BottomRight => AnchorPositionMode . Right ,
204- ExifOrientationMode . LeftTop or ExifOrientationMode . LeftBottom => AnchorPositionMode . Bottom ,
205- ExifOrientationMode . RightTop or ExifOrientationMode . RightBottom => AnchorPositionMode . Top ,
265+ ExifOrientationMode . TopRight or ExifOrientationMode . BottomLeft => AnchorPositionMode . Right ,
266+ ExifOrientationMode . LeftTop or ExifOrientationMode . LeftBottom => AnchorPositionMode . Top ,
267+ ExifOrientationMode . RightTop or ExifOrientationMode . RightBottom => AnchorPositionMode . Bottom ,
206268 _ => anchor ,
207269 } ,
208270 AnchorPositionMode . Right => orientation switch
209271 {
210- ExifOrientationMode . TopRight or ExifOrientationMode . BottomRight => AnchorPositionMode . Left ,
272+ ExifOrientationMode . TopRight or ExifOrientationMode . BottomLeft => AnchorPositionMode . Left ,
211273 ExifOrientationMode . LeftTop or ExifOrientationMode . LeftBottom => AnchorPositionMode . Top ,
212274 ExifOrientationMode . RightTop or ExifOrientationMode . RightBottom => AnchorPositionMode . Bottom ,
213275 _ => anchor ,
214276 } ,
215277 AnchorPositionMode . TopLeft => orientation switch
216278 {
217- ExifOrientationMode . BottomLeft or ExifOrientationMode . LeftTop => AnchorPositionMode . BottomLeft ,
218- ExifOrientationMode . TopRight or ExifOrientationMode . RightBottom => AnchorPositionMode . TopRight ,
219- ExifOrientationMode . BottomRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . BottomRight ,
279+ ExifOrientationMode . TopRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . TopRight ,
280+ ExifOrientationMode . BottomRight or ExifOrientationMode . RightTop => AnchorPositionMode . BottomLeft ,
281+ ExifOrientationMode . BottomLeft or ExifOrientationMode . RightBottom => AnchorPositionMode . BottomRight ,
220282 _ => anchor ,
221283 } ,
222284 AnchorPositionMode . TopRight => orientation switch
223285 {
224- ExifOrientationMode . TopRight or ExifOrientationMode . LeftTop => AnchorPositionMode . TopLeft ,
225- ExifOrientationMode . BottomLeft or ExifOrientationMode . RightBottom => AnchorPositionMode . BottomRight ,
226- ExifOrientationMode . BottomRight or ExifOrientationMode . RightTop => AnchorPositionMode . BottomLeft ,
286+ ExifOrientationMode . TopRight or ExifOrientationMode . RightTop => AnchorPositionMode . TopLeft ,
287+ ExifOrientationMode . BottomRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . BottomRight ,
288+ ExifOrientationMode . BottomLeft or ExifOrientationMode . LeftTop => AnchorPositionMode . BottomLeft ,
227289 _ => anchor ,
228290 } ,
229291 AnchorPositionMode . BottomRight => orientation switch
230292 {
231- ExifOrientationMode . TopRight or ExifOrientationMode . RightBottom => AnchorPositionMode . BottomLeft ,
232- ExifOrientationMode . BottomLeft or ExifOrientationMode . LeftTop => AnchorPositionMode . TopRight ,
233- ExifOrientationMode . BottomRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . TopLeft ,
293+ ExifOrientationMode . TopRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . BottomLeft ,
294+ ExifOrientationMode . BottomRight or ExifOrientationMode . RightTop => AnchorPositionMode . TopRight ,
295+ ExifOrientationMode . BottomLeft or ExifOrientationMode . RightBottom => AnchorPositionMode . TopLeft ,
234296 _ => anchor ,
235297 } ,
236298 AnchorPositionMode . BottomLeft => orientation switch
237299 {
238- ExifOrientationMode . TopRight or ExifOrientationMode . LeftTop => AnchorPositionMode . BottomRight ,
239- ExifOrientationMode . BottomLeft or ExifOrientationMode . RightBottom => AnchorPositionMode . TopLeft ,
240- ExifOrientationMode . BottomRight or ExifOrientationMode . RightTop => AnchorPositionMode . TopRight ,
300+ ExifOrientationMode . TopRight or ExifOrientationMode . RightTop => AnchorPositionMode . BottomRight ,
301+ ExifOrientationMode . BottomRight or ExifOrientationMode . LeftBottom => AnchorPositionMode . TopLeft ,
302+ ExifOrientationMode . BottomLeft or ExifOrientationMode . LeftTop => AnchorPositionMode . TopRight ,
241303 _ => anchor ,
242304 } ,
243305 _ => anchor ,
0 commit comments