diff --git a/src/ImageSharp/DefaultInternalImageProcessorContext.cs b/src/ImageSharp/DefaultInternalImageProcessorContext.cs index 575525a77..6e6feed84 100644 --- a/src/ImageSharp/DefaultInternalImageProcessorContext.cs +++ b/src/ImageSharp/DefaultInternalImageProcessorContext.cs @@ -52,8 +52,8 @@ namespace SixLabors.ImageSharp if (!this.mutate && this.destination == null) { // This will only work if the first processor applied is the cloning one thus - // realistically for this optermissation to work the resize must the first processor - // applied any only up processors will take the douple data path. + // realistically for this optimization to work the resize must the first processor + // applied any only up processors will take the double data path. if (processor is ICloningImageProcessor cloningImageProcessor) { this.destination = cloningImageProcessor.CloneAndApply(this.source, rectangle); diff --git a/src/ImageSharp/Processing/Processors/CloningImageProcessor.cs b/src/ImageSharp/Processing/Processors/CloningImageProcessor.cs index fdee21ed6..4672b2ad4 100644 --- a/src/ImageSharp/Processing/Processors/CloningImageProcessor.cs +++ b/src/ImageSharp/Processing/Processors/CloningImageProcessor.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Processing if (clone.Frames.Count != source.Frames.Count) { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. The processor changed the number of frames."); + throw new ImageProcessingException($"An error occurred when processing the image using {this.GetType().Name}. The processor changed the number of frames."); } Configuration configuration = source.GetConfiguration(); @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Processing // we now need to move the pixel data/size data from one image base to another if (cloned.Frames.Count != source.Frames.Count) { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. The processor changed the number of frames."); + throw new ImageProcessingException($"An error occurred when processing the image using {this.GetType().Name}. The processor changed the number of frames."); } source.SwapPixelsBuffers(cloned); @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Processing } /// - /// Generates a deep clone of the source image that operatinos should be applied to. + /// Generates a deep clone of the source image that operations should be applied to. /// /// The source image. Cannot be null. /// The source rectangle. diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index 9d7056b67..8595e8692 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Processing.Processors public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions) : base(sampler) { - // Tansforms are inverted else the output is the opposite of the expected. + // Transforms are inverted else the output is the opposite of the expected. Matrix3x2.Invert(matrix, out matrix); this.TransformMatrix = matrix; this.targetDimensions = targetDimensions; diff --git a/src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs index 2657daaa8..00547d014 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs @@ -60,5 +60,9 @@ namespace SixLabors.ImageSharp.Processing.Processors source.SwapPixelsBuffers(targetPixels); } } + + /// + protected override void AfterImageApply(Image source, Rectangle sourceRectangle) + => TransformHelpers.UpdateDimensionalMetData(source); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs b/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs index 5c32f044a..27f9a1ace 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/InterpolatedTransformProcessorBase.cs @@ -3,9 +3,7 @@ using System; using System.Runtime.CompilerServices; -using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors { @@ -13,7 +11,7 @@ namespace SixLabors.ImageSharp.Processing.Processors /// The base class for performing interpolated affine and non-affine transforms. /// /// The pixel format. - internal abstract class InterpolatedTransformProcessorBase : CloningImageProcessor + internal abstract class InterpolatedTransformProcessorBase : TransformProcessorBase where TPixel : struct, IPixel { /// @@ -115,25 +113,5 @@ namespace SixLabors.ImageSharp.Processing.Processors return (MathF.Ceiling(scale * this.Sampler.Radius), scale, ratio); } - - /// - protected override void AfterImageApply(Image source, Image destination, Rectangle sourceRectangle) - { - ExifProfile profile = destination.MetaData.ExifProfile; - if (profile == null) - { - return; - } - - if (profile.GetValue(ExifTag.PixelXDimension) != null) - { - profile.SetValue(ExifTag.PixelXDimension, destination.Width); - } - - if (profile.GetValue(ExifTag.PixelYDimension) != null) - { - profile.SetValue(ExifTag.PixelYDimension, destination.Height); - } - } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index 463d3717d..7e547727e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Processing.Processors public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Rectangle rectangle) : base(sampler) { - // Tansforms are inverted else the output is the opposite of the expected. + // Transforms are inverted else the output is the opposite of the expected. Matrix4x4.Invert(matrix, out matrix); this.TransformMatrix = matrix; this.targetRectangle = rectangle; diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs index cb65559da..b9cb58707 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Processing.Processors /// Adapted from /// /// The pixel format. - internal abstract class ResamplingWeightedProcessor : CloningImageProcessor + internal abstract class ResamplingWeightedProcessor : TransformProcessorBase where TPixel : struct, IPixel { /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs new file mode 100644 index 000000000..7403a400e --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformProcessorBase.cs @@ -0,0 +1,20 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors +{ + /// + /// The base class for all transform processors. Any processor that changes the dimensions of the image should inherit from this. + /// + /// The pixel format. + internal abstract class TransformProcessorBase : CloningImageProcessor + where TPixel : struct, IPixel + { + /// + protected override void AfterImageApply(Image source, Image destination, Rectangle sourceRectangle) + => TransformHelpers.UpdateDimensionalMetData(destination); + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Transforms/TransformHelpers.cs b/src/ImageSharp/Processing/Transforms/TransformHelpers.cs index 119fc9eed..74cbc59d2 100644 --- a/src/ImageSharp/Processing/Transforms/TransformHelpers.cs +++ b/src/ImageSharp/Processing/Transforms/TransformHelpers.cs @@ -3,6 +3,8 @@ using System; using System.Numerics; +using SixLabors.ImageSharp.MetaData.Profiles.Exif; +using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; namespace SixLabors.ImageSharp @@ -12,6 +14,38 @@ namespace SixLabors.ImageSharp /// internal class TransformHelpers { + /// + /// Updates the dimensional metadata of a transformed image + /// + /// The pixel format. + /// The image to update + public static void UpdateDimensionalMetData(Image image) + where TPixel : struct, IPixel + { + ExifProfile profile = image.MetaData.ExifProfile; + if (profile == null) + { + return; + } + + // Removing the previously stored value allows us to set a value with our own data tag if required. + if (profile.GetValue(ExifTag.PixelXDimension) != null) + { + profile.RemoveValue(ExifTag.PixelXDimension); + profile.SetValue( + ExifTag.PixelXDimension, + image.Width <= ushort.MaxValue ? (ushort)image.Width : (uint)image.Width); + } + + if (profile.GetValue(ExifTag.PixelYDimension) != null) + { + profile.RemoveValue(ExifTag.PixelYDimension); + profile.SetValue( + ExifTag.PixelYDimension, + image.Height <= ushort.MaxValue ? (ushort)image.Height : (uint)image.Height); + } + } + /// /// Returns the bounding relative to the source for the given transformation matrix. ///