From f27eeb6be21f3c60eb38201184b0cd132b39866e Mon Sep 17 00:00:00 2001 From: James South Date: Wed, 15 Oct 2014 22:10:53 +0100 Subject: [PATCH] Fixing rotate plus resolution errors. Former-commit-id: fa8d70c55ba5bf778c557c190c89c2fcdf551a49 Former-commit-id: e7d3d40d11aae80bfe92f146287e22700871ebdd --- src/ImageProcessor.Playground/Program.cs | 7 ++- .../ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg | 3 + .../Helpers/CommonParameterParserUtility.cs | 17 ++++-- .../HttpModules/ImageProcessingModule.cs | 11 +++- src/ImageProcessor/ImageFactory.cs | 8 +-- src/ImageProcessor/Imaging/Convolution.cs | 21 +++---- .../Filters/Artistic/OilPaintingFilter.cs | 1 + .../EdgeDetection/ConvolutionFilter.cs | 12 ++-- .../Filters/Photo/ComicMatrixFilter.cs | 10 +++- .../Imaging/Helpers/Adjustments.cs | 19 +++--- src/ImageProcessor/Imaging/Helpers/Effects.cs | 1 + src/ImageProcessor/Imaging/Quantizer.cs | 2 + src/ImageProcessor/Imaging/Resizer.cs | 3 +- src/ImageProcessor/Processors/Alpha.cs | 3 +- .../Processors/BackgroundColor.cs | 1 + src/ImageProcessor/Processors/Crop.cs | 3 +- src/ImageProcessor/Processors/EntropyCrop.cs | 1 + src/ImageProcessor/Processors/Filter.cs | 1 + src/ImageProcessor/Processors/Mask.cs | 2 + src/ImageProcessor/Processors/Rotate.cs | 59 ++++++------------- src/ImageProcessor/Processors/Saturation.cs | 3 +- src/ImageProcessor/Processors/Tint.cs | 3 +- 22 files changed, 100 insertions(+), 91 deletions(-) create mode 100644 src/ImageProcessor.Playground/images/input/ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg diff --git a/src/ImageProcessor.Playground/Program.cs b/src/ImageProcessor.Playground/Program.cs index 6e509e4e0..87a8cfbb5 100644 --- a/src/ImageProcessor.Playground/Program.cs +++ b/src/ImageProcessor.Playground/Program.cs @@ -78,17 +78,18 @@ namespace ImageProcessor.PlayGround //.BackgroundColor(Color.White) //.Resize(new Size((int)(size.Width * 1.1), 0)) //.ContentAwareResize(layer) - .Constrain(size) + //.Constrain(size) + .Rotate(66) //.Mask(mask) //.Format(new PngFormat()) - //.BackgroundColor(Color.HotPink) + //.BackgroundColor(Color.Cyan) //.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80) //.Resize(layer) //.DetectEdges(new SobelEdgeFilter(), false) //.DetectEdges(new LaplacianOfGaussianEdgeFilter()) //.EntropyCrop() //.Filter(MatrixFilters.Invert) - .Filter(MatrixFilters.Comic) + //.Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.HiSatch) //.Pixelate(8) //.GaussianSharpen(10) diff --git a/src/ImageProcessor.Playground/images/input/ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg b/src/ImageProcessor.Playground/images/input/ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg new file mode 100644 index 000000000..75575a483 --- /dev/null +++ b/src/ImageProcessor.Playground/images/input/ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c296447b8ba5cc891c5668cfe5a977b6f94d6d8334bc8cfac1b9cf55cc00e343 +size 18290 diff --git a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs index bb20337eb..2280bea4b 100644 --- a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs +++ b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs @@ -35,11 +35,12 @@ namespace ImageProcessor.Web.Helpers /// The regular expression to search strings for colors. /// private static readonly Regex ColorRegex = BuildColorRegex(); - + /// /// The regular expression to search strings for angles. /// - private static readonly Regex AngleRegex = new Regex(@"(rotate|angle)(=|-)(?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)", RegexOptions.Compiled); + //private static readonly Regex AngleRegex = new Regex(@"(rotate|angle)(=|-)(?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)", RegexOptions.Compiled); + private static readonly Regex AngleRegex = new Regex(@"(rotate|angle)(=|-)(-)?\d+(.?\d+)?", RegexOptions.Compiled); /// /// The regular expression to search strings for values between 1 and 100. @@ -70,14 +71,18 @@ namespace ImageProcessor.Web.Helpers /// /// The correct containing the angle for the given string. /// - public static int ParseAngle(string input) + public static float ParseAngle(string input) { foreach (Match match in AngleRegex.Matches(input)) { // Split on angle - int angle; - string value = match.Value.Split(new[] { '=', '-' })[1]; - int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out angle); + float angle; + string value = match.Value; + value = match.Value.ToUpperInvariant().Contains("ANGLE") + ? value.Substring(value.IndexOf("-", System.StringComparison.Ordinal) + 1) + : match.Value.Split('=')[1]; + + float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out angle); return angle; } diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index d918e0ffe..e222c52af 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -268,6 +268,13 @@ namespace ImageProcessor.Web.HttpModules private async Task ProcessImageAsync(HttpContext context) { HttpRequest request = context.Request; + + // SHould we ignore this request? + if (request.RawUrl.ToUpperInvariant().Contains("IPIGNORE=TRUE")) + { + return; + } + IImageService currentService = this.GetImageServiceForRequest(request); if (currentService != null) @@ -357,9 +364,7 @@ namespace ImageProcessor.Web.HttpModules if (isNewOrUpdated) { // Process the image. - using ( - ImageFactory imageFactory = - new ImageFactory(preserveExifMetaData != null && preserveExifMetaData.Value)) + using (ImageFactory imageFactory = new ImageFactory(preserveExifMetaData != null && preserveExifMetaData.Value)) { using (await Locker.LockAsync(cachedPath)) { diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index ae92ef6ad..3957fcb26 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -829,16 +829,10 @@ namespace ImageProcessor /// /// The current instance of the class. /// - public ImageFactory Rotate(int degrees) + public ImageFactory Rotate(float degrees) { if (this.ShouldProcess) { - // Sanitize the input. - if (degrees > 360 || degrees < 0) - { - degrees = 0; - } - Rotate rotate = new Rotate { DynamicParameter = degrees }; this.CurrentImageFormat.ApplyProcessor(rotate.ProcessImage, this); } diff --git a/src/ImageProcessor/Imaging/Convolution.cs b/src/ImageProcessor/Imaging/Convolution.cs index 36e57df41..554375b6d 100644 --- a/src/ImageProcessor/Imaging/Convolution.cs +++ b/src/ImageProcessor/Imaging/Convolution.cs @@ -256,18 +256,19 @@ namespace ImageProcessor.Imaging /// /// Processes the given kernel to produce an array of pixels representing a bitmap. /// - /// The image to process. + /// The image to process. /// The Gaussian kernel to use when performing the method /// A processed bitmap. - public Bitmap ProcessKernel(Bitmap sourceBitmap, double[,] kernel) + public Bitmap ProcessKernel(Bitmap source, double[,] kernel) { - int width = sourceBitmap.Width; - int height = sourceBitmap.Height; - Bitmap destinationBitmap = new Bitmap(width, height); + int width = source.Width; + int height = source.Height; + Bitmap destination = new Bitmap(width, height); + destination.SetResolution(source.HorizontalResolution, source.VerticalResolution); - using (FastBitmap sourceFastBitmap = new FastBitmap(sourceBitmap)) + using (FastBitmap sourceBitmap = new FastBitmap(source)) { - using (FastBitmap destinationFastBitmap = new FastBitmap(destinationBitmap)) + using (FastBitmap destinationBitmap = new FastBitmap(destination)) { int kernelLength = kernel.GetLength(0); int radius = kernelLength >> 1; @@ -326,7 +327,7 @@ namespace ImageProcessor.Imaging if (offsetX < width) { // ReSharper disable once AccessToDisposedClosure - Color color = sourceFastBitmap.GetPixel(offsetX, offsetY); + Color color = sourceBitmap.GetPixel(offsetX, offsetY); double k = kernel[i, j]; divider += k; @@ -372,13 +373,13 @@ namespace ImageProcessor.Imaging alpha += threshold; // ReSharper disable once AccessToDisposedClosure - destinationFastBitmap.SetPixel(x, y, Color.FromArgb(alpha.ToByte(), red.ToByte(), green.ToByte(), blue.ToByte())); + destinationBitmap.SetPixel(x, y, Color.FromArgb(alpha.ToByte(), red.ToByte(), green.ToByte(), blue.ToByte())); } }); } } - return destinationBitmap; + return destination; } #region Private diff --git a/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs b/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs index 0208edbd5..e79d8b53c 100644 --- a/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs @@ -101,6 +101,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic int radius = this.brushSize >> 1; Bitmap destination = new Bitmap(width, height); + destination.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (FastBitmap sourceBitmap = new FastBitmap(source)) { using (FastBitmap destinationBitmap = new FastBitmap(destination)) diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs index 5d0fc1e36..750f072d2 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs @@ -58,8 +58,10 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection int width = source.Width; int height = source.Height; - Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb); - Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb); + Bitmap destination = new Bitmap(width, height); + Bitmap input = new Bitmap(width, height); + destination.SetResolution(source.HorizontalResolution, source.VerticalResolution); + input.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics graphics = Graphics.FromImage(input)) { @@ -193,8 +195,10 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection int width = source.Width; int height = source.Height; - Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb); - Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb); + Bitmap destination = new Bitmap(width, height); + Bitmap input = new Bitmap(width, height); + destination.SetResolution(source.HorizontalResolution, source.VerticalResolution); + input.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics graphics = Graphics.FromImage(input)) { diff --git a/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs index f6cefeb3d..54a578f19 100644 --- a/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs @@ -59,13 +59,15 @@ namespace ImageProcessor.Imaging.Filters.Photo attributes.SetColorMatrix(ColorMatrixes.ComicHigh); // Draw the image with the high comic colormatrix. - highBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + highBitmap = new Bitmap(rectangle.Width, rectangle.Height); + highBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution); // Apply a oil painting filter to the image. highBitmap = new OilPaintingFilter(3, 5).ApplyFilter((Bitmap)image); // Draw the edges. edgeBitmap = new Bitmap(width, height); + edgeBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution); edgeBitmap = Trace(image, edgeBitmap, 120); using (Graphics graphics = Graphics.FromImage(highBitmap)) @@ -74,7 +76,8 @@ namespace ImageProcessor.Imaging.Filters.Photo } // Create a bitmap for overlaying. - lowBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + lowBitmap = new Bitmap(rectangle.Width, rectangle.Height); + lowBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution); // Set the color matrix attributes.SetColorMatrix(this.Matrix); @@ -87,7 +90,8 @@ namespace ImageProcessor.Imaging.Filters.Photo // We need to create a new image now with a pattern mask to paint it // onto the other image with. - patternBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + patternBitmap = new Bitmap(rectangle.Width, rectangle.Height); + patternBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution); // Create the pattern mask. using (Graphics graphics = Graphics.FromImage(patternBitmap)) diff --git a/src/ImageProcessor/Imaging/Helpers/Adjustments.cs b/src/ImageProcessor/Imaging/Helpers/Adjustments.cs index 245d2689e..3550639df 100644 --- a/src/ImageProcessor/Imaging/Helpers/Adjustments.cs +++ b/src/ImageProcessor/Imaging/Helpers/Adjustments.cs @@ -101,15 +101,16 @@ namespace ImageProcessor.Imaging.Helpers contrastFactor++; float factorTransform = 0.5f * (1.0f - contrastFactor); - ColorMatrix colorMatrix = new ColorMatrix( - new[] - { - new[] { contrastFactor, 0, 0, 0, 0 }, - new[] { 0, contrastFactor, 0, 0, 0 }, - new[] { 0, 0, contrastFactor, 0, 0 }, - new float[] { 0, 0, 0, 1, 0 }, - new[] { factorTransform, factorTransform, factorTransform, 0, 1 } - }); + ColorMatrix colorMatrix = + new ColorMatrix( + new[] + { + new[] { contrastFactor, 0, 0, 0, 0 }, + new[] { 0, contrastFactor, 0, 0, 0 }, + new[] { 0, 0, contrastFactor, 0, 0 }, + new float[] { 0, 0, 0, 1, 0 }, + new[] { factorTransform, factorTransform, factorTransform, 0, 1 } + }); using (Graphics graphics = Graphics.FromImage(source)) { diff --git a/src/ImageProcessor/Imaging/Helpers/Effects.cs b/src/ImageProcessor/Imaging/Helpers/Effects.cs index 7cef4ebea..b2ce5c740 100644 --- a/src/ImageProcessor/Imaging/Helpers/Effects.cs +++ b/src/ImageProcessor/Imaging/Helpers/Effects.cs @@ -166,6 +166,7 @@ namespace ImageProcessor.Imaging.Helpers // Ensure the background is cleared out on non alpha supporting formats. Bitmap clear = new Bitmap(width, height); + clear.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics graphics = Graphics.FromImage(clear)) { graphics.Clear(Color.Transparent); diff --git a/src/ImageProcessor/Imaging/Quantizer.cs b/src/ImageProcessor/Imaging/Quantizer.cs index 30c8bea4b..e51ffce02 100644 --- a/src/ImageProcessor/Imaging/Quantizer.cs +++ b/src/ImageProcessor/Imaging/Quantizer.cs @@ -62,9 +62,11 @@ namespace ImageProcessor.Imaging // First off take a 32bpp copy of the image Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb); + copy.SetResolution(source.HorizontalResolution, source.VerticalResolution); // And construct an 8bpp version Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed); + output.SetResolution(source.HorizontalResolution, source.VerticalResolution); // Now lock the bitmap into memory using (Graphics g = Graphics.FromImage(copy)) diff --git a/src/ImageProcessor/Imaging/Resizer.cs b/src/ImageProcessor/Imaging/Resizer.cs index ed774ceea..39a0af8e3 100644 --- a/src/ImageProcessor/Imaging/Resizer.cs +++ b/src/ImageProcessor/Imaging/Resizer.cs @@ -312,7 +312,8 @@ namespace ImageProcessor.Imaging return source; } - newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb); + newImage = new Bitmap(width, height); + newImage.SetResolution(source.HorizontalResolution, source.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { diff --git a/src/ImageProcessor/Processors/Alpha.cs b/src/ImageProcessor/Processors/Alpha.cs index 85254ce71..5adff071b 100644 --- a/src/ImageProcessor/Processors/Alpha.cs +++ b/src/ImageProcessor/Processors/Alpha.cs @@ -67,7 +67,8 @@ namespace ImageProcessor.Processors { int alphaPercent = this.DynamicParameter; - newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb); + newImage = new Bitmap(image.Width, image.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix00 = colorMatrix.Matrix11 = colorMatrix.Matrix22 = colorMatrix.Matrix44 = 1; diff --git a/src/ImageProcessor/Processors/BackgroundColor.cs b/src/ImageProcessor/Processors/BackgroundColor.cs index c00ce6d3e..9d446f094 100644 --- a/src/ImageProcessor/Processors/BackgroundColor.cs +++ b/src/ImageProcessor/Processors/BackgroundColor.cs @@ -60,6 +60,7 @@ namespace ImageProcessor.Processors Color backgroundColor = this.DynamicParameter; newImage = new Bitmap(width, height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); // Make a graphics object from the empty bitmap. using (Graphics graphics = Graphics.FromImage(newImage)) diff --git a/src/ImageProcessor/Processors/Crop.cs b/src/ImageProcessor/Processors/Crop.cs index c65b82d34..d0cde184d 100644 --- a/src/ImageProcessor/Processors/Crop.cs +++ b/src/ImageProcessor/Processors/Crop.cs @@ -100,7 +100,8 @@ namespace ImageProcessor.Processors rectangle.Height = sourceHeight - rectangle.Y; } - newImage = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + newImage = new Bitmap(rectangle.Width, rectangle.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { diff --git a/src/ImageProcessor/Processors/EntropyCrop.cs b/src/ImageProcessor/Processors/EntropyCrop.cs index 28210fe1e..142600f34 100644 --- a/src/ImageProcessor/Processors/EntropyCrop.cs +++ b/src/ImageProcessor/Processors/EntropyCrop.cs @@ -66,6 +66,7 @@ namespace ImageProcessor.Processors Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0); newImage = new Bitmap(rectangle.Width, rectangle.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { graphics.DrawImage( diff --git a/src/ImageProcessor/Processors/Filter.cs b/src/ImageProcessor/Processors/Filter.cs index a9197ce83..25b3f2132 100644 --- a/src/ImageProcessor/Processors/Filter.cs +++ b/src/ImageProcessor/Processors/Filter.cs @@ -66,6 +66,7 @@ namespace ImageProcessor.Processors try { newImage = new Bitmap(image.Width, image.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); IMatrixFilter matrix = this.DynamicParameter; newImage = matrix.TransformImage(image, newImage); diff --git a/src/ImageProcessor/Processors/Mask.cs b/src/ImageProcessor/Processors/Mask.cs index 44b61bc8f..86f990a5f 100644 --- a/src/ImageProcessor/Processors/Mask.cs +++ b/src/ImageProcessor/Processors/Mask.cs @@ -81,6 +81,7 @@ namespace ImageProcessor.Processors Rectangle parent = new Rectangle(0, 0, width, height); Rectangle child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A); maskCropped = new Bitmap(child.Width, child.Height); + maskCropped.SetResolution(image.HorizontalResolution, image.VerticalResolution); // First crop any bounding transparency. using (Graphics graphics = Graphics.FromImage(maskCropped)) @@ -98,6 +99,7 @@ namespace ImageProcessor.Processors // Now position the mask in an image of the same dimensions as the original. maskPositioned = new Bitmap(width, height); + maskPositioned.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(maskPositioned)) { graphics.Clear(Color.Transparent); diff --git a/src/ImageProcessor/Processors/Rotate.cs b/src/ImageProcessor/Processors/Rotate.cs index 2e5931dcc..2cd57a665 100644 --- a/src/ImageProcessor/Processors/Rotate.cs +++ b/src/ImageProcessor/Processors/Rotate.cs @@ -65,7 +65,7 @@ namespace ImageProcessor.Processors try { - int angle = this.DynamicParameter; + float angle = this.DynamicParameter; // Center of the image float rotateAtX = Math.Abs(image.Width / 2); @@ -104,50 +104,27 @@ namespace ImageProcessor.Processors /// private Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle) { - int width, height, x, y; - - // Degrees to radians according to Google. - const double DegreeToRadian = 0.0174532925; - double widthAsDouble = image.Width; double heightAsDouble = image.Height; - // Allow for angles over 180 - if (angle > 180) - { - angle = angle - 360; - } + double radians = angle * Math.PI / 180d; + double radiansSin = Math.Sin(radians); + double radiansCos = Math.Cos(radians); + double width1 = (heightAsDouble * radiansSin) + (widthAsDouble * radiansCos); + double height1 = (widthAsDouble * radiansSin) + (heightAsDouble * radiansCos); - double degrees = Math.Abs(angle); + // Find dimensions in the other direction + radiansSin = Math.Sin(-radians); + radiansCos = Math.Cos(-radians); + double width2 = (heightAsDouble * radiansSin) + (widthAsDouble * radiansCos); + double height2 = (widthAsDouble * radiansSin) + (heightAsDouble * radiansCos); - if (degrees <= 90) - { - double radians = DegreeToRadian * degrees; - double radiansSin = Math.Sin(radians); - double radiansCos = Math.Cos(radians); - width = (int)((heightAsDouble * radiansSin) + (widthAsDouble * radiansCos)); - height = (int)((widthAsDouble * radiansSin) + (heightAsDouble * radiansCos)); - x = (width - image.Width) / 2; - y = (height - image.Height) / 2; - } - else - { - degrees -= 90; - double radians = DegreeToRadian * degrees; - double radiansSin = Math.Sin(radians); - double radiansCos = Math.Cos(radians); + // Get the external vertex for the rotation + int width = Convert.ToInt32(Math.Max(Math.Abs(width1), Math.Abs(width2))); + int height = Convert.ToInt32(Math.Max(Math.Abs(height1), Math.Abs(height2))); - // Fix the 270 error - if (Math.Abs(radiansCos - -1.0D) < 0.00001) - { - radiansCos = 1; - } - - width = (int)((widthAsDouble * radiansSin) + (heightAsDouble * radiansCos)); - height = (int)((heightAsDouble * radiansSin) + (widthAsDouble * radiansCos)); - x = (width - image.Width) / 2; - y = (height - image.Height) / 2; - } + int x = (width - image.Width) / 2; + int y = (height - image.Height) / 2; // Create a new empty bitmap to hold rotated image Bitmap newImage = new Bitmap(width, height); @@ -157,7 +134,7 @@ namespace ImageProcessor.Processors using (Graphics graphics = Graphics.FromImage(newImage)) { // Reduce the jagged edge. - graphics.SmoothingMode = SmoothingMode.HighQuality; + graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality; @@ -172,7 +149,7 @@ namespace ImageProcessor.Processors graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y); // Draw passed in image onto graphics object - graphics.DrawImage(image, new PointF(0 + x, 0 + y)); + graphics.DrawImage(image, new PointF(x, y)); } return newImage; diff --git a/src/ImageProcessor/Processors/Saturation.cs b/src/ImageProcessor/Processors/Saturation.cs index ede958489..10fbbbb1c 100644 --- a/src/ImageProcessor/Processors/Saturation.cs +++ b/src/ImageProcessor/Processors/Saturation.cs @@ -81,7 +81,8 @@ namespace ImageProcessor.Processors float saturationComplementG = 0.6094f * saturationComplement; float saturationComplementB = 0.0820f * saturationComplement; - newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb); + newImage = new Bitmap(image.Width, image.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); ColorMatrix colorMatrix = new ColorMatrix( diff --git a/src/ImageProcessor/Processors/Tint.cs b/src/ImageProcessor/Processors/Tint.cs index 603c7fd11..9fe68295d 100644 --- a/src/ImageProcessor/Processors/Tint.cs +++ b/src/ImageProcessor/Processors/Tint.cs @@ -69,7 +69,8 @@ namespace ImageProcessor.Processors }; ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements); - newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb); + newImage = new Bitmap(image.Width, image.Height); + newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) {