Browse Source

Fixing rotate plus resolution errors.

Former-commit-id: fa8d70c55ba5bf778c557c190c89c2fcdf551a49
Former-commit-id: e7d3d40d11aae80bfe92f146287e22700871ebdd
af/merge-core
James South 12 years ago
parent
commit
f27eeb6be2
  1. 7
      src/ImageProcessor.Playground/Program.cs
  2. 3
      src/ImageProcessor.Playground/images/input/ce1a34f6-52bd-11e4-8164-54281a6247c9.jpg
  3. 17
      src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs
  4. 11
      src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
  5. 8
      src/ImageProcessor/ImageFactory.cs
  6. 21
      src/ImageProcessor/Imaging/Convolution.cs
  7. 1
      src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs
  8. 12
      src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs
  9. 10
      src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs
  10. 19
      src/ImageProcessor/Imaging/Helpers/Adjustments.cs
  11. 1
      src/ImageProcessor/Imaging/Helpers/Effects.cs
  12. 2
      src/ImageProcessor/Imaging/Quantizer.cs
  13. 3
      src/ImageProcessor/Imaging/Resizer.cs
  14. 3
      src/ImageProcessor/Processors/Alpha.cs
  15. 1
      src/ImageProcessor/Processors/BackgroundColor.cs
  16. 3
      src/ImageProcessor/Processors/Crop.cs
  17. 1
      src/ImageProcessor/Processors/EntropyCrop.cs
  18. 1
      src/ImageProcessor/Processors/Filter.cs
  19. 2
      src/ImageProcessor/Processors/Mask.cs
  20. 59
      src/ImageProcessor/Processors/Rotate.cs
  21. 3
      src/ImageProcessor/Processors/Saturation.cs
  22. 3
      src/ImageProcessor/Processors/Tint.cs

7
src/ImageProcessor.Playground/Program.cs

@ -78,17 +78,18 @@ namespace ImageProcessor.PlayGround
//.BackgroundColor(Color.White) //.BackgroundColor(Color.White)
//.Resize(new Size((int)(size.Width * 1.1), 0)) //.Resize(new Size((int)(size.Width * 1.1), 0))
//.ContentAwareResize(layer) //.ContentAwareResize(layer)
.Constrain(size) //.Constrain(size)
.Rotate(66)
//.Mask(mask) //.Mask(mask)
//.Format(new PngFormat()) //.Format(new PngFormat())
//.BackgroundColor(Color.HotPink) //.BackgroundColor(Color.Cyan)
//.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80) //.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80)
//.Resize(layer) //.Resize(layer)
//.DetectEdges(new SobelEdgeFilter(), false) //.DetectEdges(new SobelEdgeFilter(), false)
//.DetectEdges(new LaplacianOfGaussianEdgeFilter()) //.DetectEdges(new LaplacianOfGaussianEdgeFilter())
//.EntropyCrop() //.EntropyCrop()
//.Filter(MatrixFilters.Invert) //.Filter(MatrixFilters.Invert)
.Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.Comic)
//.Filter(MatrixFilters.HiSatch) //.Filter(MatrixFilters.HiSatch)
//.Pixelate(8) //.Pixelate(8)
//.GaussianSharpen(10) //.GaussianSharpen(10)

3
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

17
src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs

@ -35,11 +35,12 @@ namespace ImageProcessor.Web.Helpers
/// The regular expression to search strings for colors. /// The regular expression to search strings for colors.
/// </summary> /// </summary>
private static readonly Regex ColorRegex = BuildColorRegex(); private static readonly Regex ColorRegex = BuildColorRegex();
/// <summary> /// <summary>
/// The regular expression to search strings for angles. /// The regular expression to search strings for angles.
/// </summary> /// </summary>
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);
/// <summary> /// <summary>
/// The regular expression to search strings for values between 1 and 100. /// The regular expression to search strings for values between 1 and 100.
@ -70,14 +71,18 @@ namespace ImageProcessor.Web.Helpers
/// <returns> /// <returns>
/// The correct <see cref="T:System.Int32"/> containing the angle for the given string. /// The correct <see cref="T:System.Int32"/> containing the angle for the given string.
/// </returns> /// </returns>
public static int ParseAngle(string input) public static float ParseAngle(string input)
{ {
foreach (Match match in AngleRegex.Matches(input)) foreach (Match match in AngleRegex.Matches(input))
{ {
// Split on angle // Split on angle
int angle; float angle;
string value = match.Value.Split(new[] { '=', '-' })[1]; string value = match.Value;
int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out angle); 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; return angle;
} }

11
src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs

@ -268,6 +268,13 @@ namespace ImageProcessor.Web.HttpModules
private async Task ProcessImageAsync(HttpContext context) private async Task ProcessImageAsync(HttpContext context)
{ {
HttpRequest request = context.Request; HttpRequest request = context.Request;
// SHould we ignore this request?
if (request.RawUrl.ToUpperInvariant().Contains("IPIGNORE=TRUE"))
{
return;
}
IImageService currentService = this.GetImageServiceForRequest(request); IImageService currentService = this.GetImageServiceForRequest(request);
if (currentService != null) if (currentService != null)
@ -357,9 +364,7 @@ namespace ImageProcessor.Web.HttpModules
if (isNewOrUpdated) if (isNewOrUpdated)
{ {
// Process the image. // Process the image.
using ( using (ImageFactory imageFactory = new ImageFactory(preserveExifMetaData != null && preserveExifMetaData.Value))
ImageFactory imageFactory =
new ImageFactory(preserveExifMetaData != null && preserveExifMetaData.Value))
{ {
using (await Locker.LockAsync(cachedPath)) using (await Locker.LockAsync(cachedPath))
{ {

8
src/ImageProcessor/ImageFactory.cs

@ -829,16 +829,10 @@ namespace ImageProcessor
/// <returns> /// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class. /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns> /// </returns>
public ImageFactory Rotate(int degrees) public ImageFactory Rotate(float degrees)
{ {
if (this.ShouldProcess) if (this.ShouldProcess)
{ {
// Sanitize the input.
if (degrees > 360 || degrees < 0)
{
degrees = 0;
}
Rotate rotate = new Rotate { DynamicParameter = degrees }; Rotate rotate = new Rotate { DynamicParameter = degrees };
this.CurrentImageFormat.ApplyProcessor(rotate.ProcessImage, this); this.CurrentImageFormat.ApplyProcessor(rotate.ProcessImage, this);
} }

21
src/ImageProcessor/Imaging/Convolution.cs

@ -256,18 +256,19 @@ namespace ImageProcessor.Imaging
/// <summary> /// <summary>
/// Processes the given kernel to produce an array of pixels representing a bitmap. /// Processes the given kernel to produce an array of pixels representing a bitmap.
/// </summary> /// </summary>
/// <param name="sourceBitmap">The image to process.</param> /// <param name="source">The image to process.</param>
/// <param name="kernel">The Gaussian kernel to use when performing the method</param> /// <param name="kernel">The Gaussian kernel to use when performing the method</param>
/// <returns>A processed bitmap.</returns> /// <returns>A processed bitmap.</returns>
public Bitmap ProcessKernel(Bitmap sourceBitmap, double[,] kernel) public Bitmap ProcessKernel(Bitmap source, double[,] kernel)
{ {
int width = sourceBitmap.Width; int width = source.Width;
int height = sourceBitmap.Height; int height = source.Height;
Bitmap destinationBitmap = new Bitmap(width, 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 kernelLength = kernel.GetLength(0);
int radius = kernelLength >> 1; int radius = kernelLength >> 1;
@ -326,7 +327,7 @@ namespace ImageProcessor.Imaging
if (offsetX < width) if (offsetX < width)
{ {
// ReSharper disable once AccessToDisposedClosure // ReSharper disable once AccessToDisposedClosure
Color color = sourceFastBitmap.GetPixel(offsetX, offsetY); Color color = sourceBitmap.GetPixel(offsetX, offsetY);
double k = kernel[i, j]; double k = kernel[i, j];
divider += k; divider += k;
@ -372,13 +373,13 @@ namespace ImageProcessor.Imaging
alpha += threshold; alpha += threshold;
// ReSharper disable once AccessToDisposedClosure // 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 #region Private

1
src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs

@ -101,6 +101,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
int radius = this.brushSize >> 1; int radius = this.brushSize >> 1;
Bitmap destination = new Bitmap(width, height); Bitmap destination = new Bitmap(width, height);
destination.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (FastBitmap sourceBitmap = new FastBitmap(source)) using (FastBitmap sourceBitmap = new FastBitmap(source))
{ {
using (FastBitmap destinationBitmap = new FastBitmap(destination)) using (FastBitmap destinationBitmap = new FastBitmap(destination))

12
src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs

@ -58,8 +58,10 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection
int width = source.Width; int width = source.Width;
int height = source.Height; int height = source.Height;
Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb); Bitmap destination = new Bitmap(width, height);
Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb); Bitmap input = new Bitmap(width, height);
destination.SetResolution(source.HorizontalResolution, source.VerticalResolution);
input.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(input)) using (Graphics graphics = Graphics.FromImage(input))
{ {
@ -193,8 +195,10 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection
int width = source.Width; int width = source.Width;
int height = source.Height; int height = source.Height;
Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb); Bitmap destination = new Bitmap(width, height);
Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb); Bitmap input = new Bitmap(width, height);
destination.SetResolution(source.HorizontalResolution, source.VerticalResolution);
input.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(input)) using (Graphics graphics = Graphics.FromImage(input))
{ {

10
src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs

@ -59,13 +59,15 @@ namespace ImageProcessor.Imaging.Filters.Photo
attributes.SetColorMatrix(ColorMatrixes.ComicHigh); attributes.SetColorMatrix(ColorMatrixes.ComicHigh);
// Draw the image with the high comic colormatrix. // 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. // Apply a oil painting filter to the image.
highBitmap = new OilPaintingFilter(3, 5).ApplyFilter((Bitmap)image); highBitmap = new OilPaintingFilter(3, 5).ApplyFilter((Bitmap)image);
// Draw the edges. // Draw the edges.
edgeBitmap = new Bitmap(width, height); edgeBitmap = new Bitmap(width, height);
edgeBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
edgeBitmap = Trace(image, edgeBitmap, 120); edgeBitmap = Trace(image, edgeBitmap, 120);
using (Graphics graphics = Graphics.FromImage(highBitmap)) using (Graphics graphics = Graphics.FromImage(highBitmap))
@ -74,7 +76,8 @@ namespace ImageProcessor.Imaging.Filters.Photo
} }
// Create a bitmap for overlaying. // 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 // Set the color matrix
attributes.SetColorMatrix(this.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 // We need to create a new image now with a pattern mask to paint it
// onto the other image with. // 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. // Create the pattern mask.
using (Graphics graphics = Graphics.FromImage(patternBitmap)) using (Graphics graphics = Graphics.FromImage(patternBitmap))

19
src/ImageProcessor/Imaging/Helpers/Adjustments.cs

@ -101,15 +101,16 @@ namespace ImageProcessor.Imaging.Helpers
contrastFactor++; contrastFactor++;
float factorTransform = 0.5f * (1.0f - contrastFactor); float factorTransform = 0.5f * (1.0f - contrastFactor);
ColorMatrix colorMatrix = new ColorMatrix( ColorMatrix colorMatrix =
new[] new ColorMatrix(
{ new[]
new[] { contrastFactor, 0, 0, 0, 0 }, {
new[] { 0, contrastFactor, 0, 0, 0 }, new[] { contrastFactor, 0, 0, 0, 0 },
new[] { 0, 0, contrastFactor, 0, 0 }, new[] { 0, contrastFactor, 0, 0, 0 },
new float[] { 0, 0, 0, 1, 0 }, new[] { 0, 0, contrastFactor, 0, 0 },
new[] { factorTransform, factorTransform, factorTransform, 0, 1 } new float[] { 0, 0, 0, 1, 0 },
}); new[] { factorTransform, factorTransform, factorTransform, 0, 1 }
});
using (Graphics graphics = Graphics.FromImage(source)) using (Graphics graphics = Graphics.FromImage(source))
{ {

1
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. // Ensure the background is cleared out on non alpha supporting formats.
Bitmap clear = new Bitmap(width, height); Bitmap clear = new Bitmap(width, height);
clear.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(clear)) using (Graphics graphics = Graphics.FromImage(clear))
{ {
graphics.Clear(Color.Transparent); graphics.Clear(Color.Transparent);

2
src/ImageProcessor/Imaging/Quantizer.cs

@ -62,9 +62,11 @@ namespace ImageProcessor.Imaging
// First off take a 32bpp copy of the image // First off take a 32bpp copy of the image
Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb); Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb);
copy.SetResolution(source.HorizontalResolution, source.VerticalResolution);
// And construct an 8bpp version // And construct an 8bpp version
Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed); Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
output.SetResolution(source.HorizontalResolution, source.VerticalResolution);
// Now lock the bitmap into memory // Now lock the bitmap into memory
using (Graphics g = Graphics.FromImage(copy)) using (Graphics g = Graphics.FromImage(copy))

3
src/ImageProcessor/Imaging/Resizer.cs

@ -312,7 +312,8 @@ namespace ImageProcessor.Imaging
return source; 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)) using (Graphics graphics = Graphics.FromImage(newImage))
{ {

3
src/ImageProcessor/Processors/Alpha.cs

@ -67,7 +67,8 @@ namespace ImageProcessor.Processors
{ {
int alphaPercent = this.DynamicParameter; 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 colorMatrix = new ColorMatrix();
colorMatrix.Matrix00 = colorMatrix.Matrix11 = colorMatrix.Matrix22 = colorMatrix.Matrix44 = 1; colorMatrix.Matrix00 = colorMatrix.Matrix11 = colorMatrix.Matrix22 = colorMatrix.Matrix44 = 1;

1
src/ImageProcessor/Processors/BackgroundColor.cs

@ -60,6 +60,7 @@ namespace ImageProcessor.Processors
Color backgroundColor = this.DynamicParameter; Color backgroundColor = this.DynamicParameter;
newImage = new Bitmap(width, height); newImage = new Bitmap(width, height);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
// Make a graphics object from the empty bitmap. // Make a graphics object from the empty bitmap.
using (Graphics graphics = Graphics.FromImage(newImage)) using (Graphics graphics = Graphics.FromImage(newImage))

3
src/ImageProcessor/Processors/Crop.cs

@ -100,7 +100,8 @@ namespace ImageProcessor.Processors
rectangle.Height = sourceHeight - rectangle.Y; 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)) using (Graphics graphics = Graphics.FromImage(newImage))
{ {

1
src/ImageProcessor/Processors/EntropyCrop.cs

@ -66,6 +66,7 @@ namespace ImageProcessor.Processors
Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0); Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0);
newImage = new Bitmap(rectangle.Width, rectangle.Height); newImage = new Bitmap(rectangle.Width, rectangle.Height);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(newImage)) using (Graphics graphics = Graphics.FromImage(newImage))
{ {
graphics.DrawImage( graphics.DrawImage(

1
src/ImageProcessor/Processors/Filter.cs

@ -66,6 +66,7 @@ namespace ImageProcessor.Processors
try try
{ {
newImage = new Bitmap(image.Width, image.Height); newImage = new Bitmap(image.Width, image.Height);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
IMatrixFilter matrix = this.DynamicParameter; IMatrixFilter matrix = this.DynamicParameter;
newImage = matrix.TransformImage(image, newImage); newImage = matrix.TransformImage(image, newImage);

2
src/ImageProcessor/Processors/Mask.cs

@ -81,6 +81,7 @@ namespace ImageProcessor.Processors
Rectangle parent = new Rectangle(0, 0, width, height); Rectangle parent = new Rectangle(0, 0, width, height);
Rectangle child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A); Rectangle child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A);
maskCropped = new Bitmap(child.Width, child.Height); maskCropped = new Bitmap(child.Width, child.Height);
maskCropped.SetResolution(image.HorizontalResolution, image.VerticalResolution);
// First crop any bounding transparency. // First crop any bounding transparency.
using (Graphics graphics = Graphics.FromImage(maskCropped)) 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. // Now position the mask in an image of the same dimensions as the original.
maskPositioned = new Bitmap(width, height); maskPositioned = new Bitmap(width, height);
maskPositioned.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(maskPositioned)) using (Graphics graphics = Graphics.FromImage(maskPositioned))
{ {
graphics.Clear(Color.Transparent); graphics.Clear(Color.Transparent);

59
src/ImageProcessor/Processors/Rotate.cs

@ -65,7 +65,7 @@ namespace ImageProcessor.Processors
try try
{ {
int angle = this.DynamicParameter; float angle = this.DynamicParameter;
// Center of the image // Center of the image
float rotateAtX = Math.Abs(image.Width / 2); float rotateAtX = Math.Abs(image.Width / 2);
@ -104,50 +104,27 @@ namespace ImageProcessor.Processors
/// </remarks> /// </remarks>
private Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle) 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 widthAsDouble = image.Width;
double heightAsDouble = image.Height; double heightAsDouble = image.Height;
// Allow for angles over 180 double radians = angle * Math.PI / 180d;
if (angle > 180) double radiansSin = Math.Sin(radians);
{ double radiansCos = Math.Cos(radians);
angle = angle - 360; 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) // Get the external vertex for the rotation
{ int width = Convert.ToInt32(Math.Max(Math.Abs(width1), Math.Abs(width2)));
double radians = DegreeToRadian * degrees; int height = Convert.ToInt32(Math.Max(Math.Abs(height1), Math.Abs(height2)));
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);
// Fix the 270 error int x = (width - image.Width) / 2;
if (Math.Abs(radiansCos - -1.0D) < 0.00001) int y = (height - image.Height) / 2;
{
radiansCos = 1;
}
width = (int)((widthAsDouble * radiansSin) + (heightAsDouble * radiansCos));
height = (int)((heightAsDouble * radiansSin) + (widthAsDouble * radiansCos));
x = (width - image.Width) / 2;
y = (height - image.Height) / 2;
}
// Create a new empty bitmap to hold rotated image // Create a new empty bitmap to hold rotated image
Bitmap newImage = new Bitmap(width, height); Bitmap newImage = new Bitmap(width, height);
@ -157,7 +134,7 @@ namespace ImageProcessor.Processors
using (Graphics graphics = Graphics.FromImage(newImage)) using (Graphics graphics = Graphics.FromImage(newImage))
{ {
// Reduce the jagged edge. // Reduce the jagged edge.
graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
@ -172,7 +149,7 @@ namespace ImageProcessor.Processors
graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y); graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y);
// Draw passed in image onto graphics object // 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; return newImage;

3
src/ImageProcessor/Processors/Saturation.cs

@ -81,7 +81,8 @@ namespace ImageProcessor.Processors
float saturationComplementG = 0.6094f * saturationComplement; float saturationComplementG = 0.6094f * saturationComplement;
float saturationComplementB = 0.0820f * 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 = ColorMatrix colorMatrix =
new ColorMatrix( new ColorMatrix(

3
src/ImageProcessor/Processors/Tint.cs

@ -69,7 +69,8 @@ namespace ImageProcessor.Processors
}; };
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements); 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)) using (Graphics graphics = Graphics.FromImage(newImage))
{ {

Loading…
Cancel
Save