Fix off-by-one errors when transforming images. #3011
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Prerequisites
Description
A proper fix for #2753 and #3000
See #3000 (comment) for the explanation of the theory.
This pull request refactors several transformation and primitive classes to improve consistency, performance, and accuracy in image processing operations. The main changes include making value type members and methods
readonlyfor better immutability and optimization, removing unnecessary parameters related to transform space, and updating transformation logic to ensure correct coordinate space handling and more accurate results.Transformation Logic and API Simplification
TransformSpaceparameter and related properties fromAffineTransformBuilderand transformation utility methods, simplifying the API and ensuring all transformations are consistently defined in pixel space. (src/ImageSharp/Processing/AffineTransformBuilder.cs[1] [2] [3] [4] [5] [6] [7]RotateProcessor,SkewProcessor,AffineTransformProcessor,ProjectiveTransformProcessor) to use new utility methods for canvas size calculation and matrix normalization, ensuring correct sampling and output dimensions. (src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs[1]src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs[2] [3]src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs[4]src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs[5]src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs[1] [2]Value Type Improvements
Point,PointF, andSizeFstructsreadonly, which improves performance and thread safety by preventing modification of struct instances. (src/ImageSharp/Primitives/Point.cs[1] [2] [3]src/ImageSharp/Primitives/PointF.cs[4] [5] [6]src/ImageSharp/Primitives/SizeF.cs[7] [8]Rectangle and Area Transformation Accuracy
ExifProfile.SyncSubjectby switching from integer to floating-point rectangles for more accurate bounds calculation, and usingMathF.Floor/MathF.Ceilingfor coordinate rounding. (src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cssrc/ImageSharp/Metadata/Profiles/Exif/ExifProfile.csL343-R354)Documentation and Naming Consistency
src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cssrc/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.csL10-R11)Internal Utility Refactoring
src/ImageSharp/Processing/AffineTransformBuilder.cssrc/ImageSharp/Processing/AffineTransformBuilder.csL347-R351)