From e154d8d74d5ca9e9460ab374461743fc1c896cd5 Mon Sep 17 00:00:00 2001 From: James South Date: Mon, 6 Jan 2014 15:45:37 +0000 Subject: [PATCH] backup before next release Updates, Gaussian blur, Gaussian sharpen, Comic filter, ImageProcessingModule Former-commit-id: 5d378518cccc5476926324ee9f669e6321fb575d --- .../NET45/Caching/DiskCache.cs | 23 +- .../HttpModules/ImageProcessingModule.cs | 11 +- src/ImageProcessor/ImageFactory.cs | 98 +++- src/ImageProcessor/ImageProcessor.csproj | 1 - src/ImageProcessor/Imaging/Convolution.cs | 140 ++---- .../Imaging/Filters/ColorMatrixes.cs | 58 ++- .../Imaging/Filters/ComicMatrixFilter.cs | 432 ++++++++++++++++-- src/ImageProcessor/Imaging/ResizeLayer.cs | 79 ++-- src/ImageProcessor/Processors/Filter.cs | 1 + src/ImageProcessor/Processors/GaussianBlur.cs | 8 +- .../Processors/GaussianSharpen.cs | 8 +- src/ImageProcessor/Processors/Resize.cs | 24 +- .../NET4/Images/Thumbs.db.REMOVED.git-id | 2 +- .../Images/Penguins-200.jpg | Bin 0 -> 10119 bytes .../Images/Thumbs.db.REMOVED.git-id | 1 + .../NET45/Test_Website_NET45/Images/emma.jpg | Bin 0 -> 29617 bytes ...EMOVED.git-id => rocks.jpg.REMOVED.git-id} | 0 .../Images/thor.jpg.REMOVED.git-id | 1 + .../Images/udendørs-374.jpg | Bin 0 -> 20944 bytes .../Test_Website_NET45.csproj | 4 + .../Views/Home/Index.cshtml | 27 +- .../NET45/Test_Website_NET45/Web.config | 2 +- 22 files changed, 697 insertions(+), 223 deletions(-) create mode 100644 src/TestWebsites/NET45/Test_Website_NET45/Images/Penguins-200.jpg create mode 100644 src/TestWebsites/NET45/Test_Website_NET45/Images/Thumbs.db.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_NET45/Images/emma.jpg rename src/TestWebsites/NET45/Test_Website_NET45/Images/{MSwanson - Wide Large - Rock 02.jpg.REMOVED.git-id => rocks.jpg.REMOVED.git-id} (100%) create mode 100644 src/TestWebsites/NET45/Test_Website_NET45/Images/thor.jpg.REMOVED.git-id create mode 100644 src/TestWebsites/NET45/Test_Website_NET45/Images/udendørs-374.jpg diff --git a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs index 9bb8917838..24d46dc282 100644 --- a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs +++ b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs @@ -179,7 +179,7 @@ namespace ImageProcessor.Web.Caching { // Can't check the last write time so check to see if the cached image is set to expire // or if the max age is different. - if (cachedImage.CreationTimeUtc.AddDays(MaxFileCachedDuration) < DateTime.UtcNow.AddDays(-MaxFileCachedDuration)) + if (this.IsExpired(cachedImage.CreationTimeUtc)) { CacheIndexer.Remove(path); isUpdated = true; @@ -208,7 +208,7 @@ namespace ImageProcessor.Web.Caching // Check to see if the last write time is different of whether the // cached image is set to expire or if the max age is different. if (!this.RoughDateTimeCompare(imageFileInfo.LastWriteTimeUtc, cachedImage.LastWriteTimeUtc) - || cachedImage.CreationTimeUtc.AddDays(MaxFileCachedDuration) < DateTime.UtcNow.AddDays(-MaxFileCachedDuration)) + || this.IsExpired(cachedImage.CreationTimeUtc)) { CacheIndexer.Remove(path); isUpdated = true; @@ -285,7 +285,6 @@ namespace ImageProcessor.Web.Caching DateTime creationTime = DateTime.MinValue.ToUniversalTime(); DateTime lastWriteTime = DateTime.MinValue.ToUniversalTime(); - if (this.isRemote) { if (cachedFileInfo.Exists) @@ -330,7 +329,8 @@ namespace ImageProcessor.Web.Caching { // If the group count is equal to the max count minus 1 then we know we // have reduced the number of items below the maximum allowed. - if (count <= MaxFilesCount - 1) + // We'll cleanup any orphaned expired files though. + if (!this.IsExpired(fileInfo.CreationTimeUtc) && count <= MaxFilesCount - 1) { break; } @@ -404,6 +404,21 @@ namespace ImageProcessor.Web.Caching return false; } + + /// + /// Gets a value indicating whether the given images creation date is out with + /// the prescribed limit. + /// + /// + /// The creation date. + /// + /// + /// The true if the date is out with the limit, otherwise; false. + /// + private bool IsExpired(DateTime creationDate) + { + return creationDate.AddDays(MaxFileCachedDuration) < DateTime.UtcNow.AddDays(-MaxFileCachedDuration); + } #endregion #endregion } diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs index 1a7296ed1c..a6a86f01d2 100644 --- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs @@ -314,8 +314,17 @@ namespace ImageProcessor.Web.HttpModules } else { + // Check to see if the file exists. + // ReSharper disable once AssignNullToNotNullAttribute + FileInfo fileInfo = new FileInfo(requestPath); + + if (!fileInfo.Exists) + { + throw new HttpException(404, "No image exists at " + fullPath); + } + imageFactory.Load(fullPath).AutoProcess().Save(cachedPath); - + // Ensure that the LastWriteTime property of the source and cached file match. Tuple creationAndLastWriteDateTimes = await cache.SetCachedLastWriteTimeAsync(); diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index adcfb9178d..4278122e88 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -364,7 +364,7 @@ namespace ImageProcessor { if (this.ShouldProcess) { - ResizeLayer layer = new ResizeLayer(size, ResizeMode.Max); + ResizeLayer layer = new ResizeLayer(size, Color.Transparent, ResizeMode.Max); return this.Resize(layer); } @@ -487,6 +487,102 @@ namespace ImageProcessor return this; } + /// + /// Uses a Gaussian kernel to blur the current image. + /// + /// + /// The sigma and threshold values applied to the kernel are + /// 1.4 and 0 respectively. + /// + /// + /// + /// + /// The size to set the Gaussian kernel to. + /// + /// + /// The current instance of the class. + /// + public ImageFactory GaussianBlur(int size) + { + if (this.ShouldProcess && size > 0) + { + GaussianLayer layer = new GaussianLayer(size); + GaussianBlur gaussianBlur = new GaussianBlur { DynamicParameter = layer }; + this.Image = gaussianBlur.ProcessImage(this); + } + + return this; + } + + /// + /// Uses a Gaussian kernel to blur the current image. + /// + /// + /// The for applying sharpening and + /// blurring methods to an image. + /// + /// + /// The current instance of the class. + /// + public ImageFactory GaussianBlur(GaussianLayer gaussianLayer) + { + if (this.ShouldProcess) + { + GaussianBlur gaussianBlur = new GaussianBlur { DynamicParameter = gaussianLayer }; + this.Image = gaussianBlur.ProcessImage(this); + } + + return this; + } + + /// + /// Uses a Gaussian kernel to sharpen the current image. + /// + /// + /// The sigma and threshold values applied to the kernel are + /// 1.4 and 0 respectively. + /// + /// + /// + /// + /// The size to set the Gaussian kernel to. + /// + /// + /// The current instance of the class. + /// + public ImageFactory GaussianSharpen(int size) + { + if (this.ShouldProcess && size > 0) + { + GaussianLayer layer = new GaussianLayer(size); + GaussianSharpen gaussianSharpen = new GaussianSharpen { DynamicParameter = layer }; + this.Image = gaussianSharpen.ProcessImage(this); + } + + return this; + } + + /// + /// Uses a Gaussian kernel to sharpen the current image. + /// + /// + /// The for applying sharpening and + /// blurring methods to an image. + /// + /// + /// The current instance of the class. + /// + public ImageFactory GaussianSharpen(GaussianLayer gaussianLayer) + { + if (this.ShouldProcess) + { + GaussianSharpen gaussianSharpen = new GaussianSharpen { DynamicParameter = gaussianLayer }; + this.Image = gaussianSharpen.ProcessImage(this); + } + + return this; + } + /// /// Alters the output quality of the current image. /// diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj index 236724acdc..bac0ae9805 100644 --- a/src/ImageProcessor/ImageProcessor.csproj +++ b/src/ImageProcessor/ImageProcessor.csproj @@ -59,7 +59,6 @@ - diff --git a/src/ImageProcessor/Imaging/Convolution.cs b/src/ImageProcessor/Imaging/Convolution.cs index 61187eb4fc..5e8aac4332 100644 --- a/src/ImageProcessor/Imaging/Convolution.cs +++ b/src/ImageProcessor/Imaging/Convolution.cs @@ -253,103 +253,34 @@ namespace ImageProcessor.Imaging } /// - /// Convert a Bitmap to an a multidimensional array of raw pixel values + /// Processes the given kernel to produce an array of pixels representing a bitmap. /// - /// The image to convert - /// a multidimensional array of raw pixel values - public Pixel[,] BitmapToPixels(Bitmap image) + /// The the image to process. + /// The Gaussian kernel to use when performing the method + /// A processed bitmap. + public Bitmap ProcessKernel(Bitmap sourceBitmap, double[,] kernel) { - Pixel[,] pixels = new Pixel[image.Width, image.Height]; + int width = sourceBitmap.Width; + int height = sourceBitmap.Height; - BitmapData sourceData = image.LockBits( - new Rectangle(0, 0, image.Width, image.Height), + BitmapData sourceData = sourceBitmap.LockBits( + new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, - image.PixelFormat); - - byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; - - Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); - image.UnlockBits(sourceData); - - int pixelSize = Image.GetPixelFormatSize(image.PixelFormat) / 8; - int stride = sourceData.Stride; - - for (int x = 0; x < image.Width; x++) - { - for (int y = 0; y < image.Height; y++) - { - int byteOffset = (y * stride) + (x * pixelSize); - - pixels[x, y] = new Pixel - { - A = pixelBuffer[byteOffset + 3], - R = pixelBuffer[byteOffset + 2], - G = pixelBuffer[byteOffset + 1], - B = pixelBuffer[byteOffset] - }; - } - } - - return pixels; - } - - /// - /// Convert a multidimensional array of raw pixel values to a bitmap - /// - /// The pixels to convert - /// a bitmap - public Bitmap PixelsToBitmap(Pixel[,] pixels) - { - int width = pixels.GetLength(0); - int height = pixels.GetLength(1); - Bitmap resultBitmap = new Bitmap(width, height); - BitmapData resultData = resultBitmap.LockBits( - new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), - ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); - byte[] pixelBuffer = new byte[resultData.Stride * resultData.Height]; - int stride = resultData.Stride; - int pixelSize = Image.GetPixelFormatSize(resultBitmap.PixelFormat) / 8; - - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - int byteOffset = (y * stride) + (x * pixelSize); + int strideWidth = sourceData.Stride; + int scanHeight = sourceData.Height; - double pixelRed = pixels[x, y].R; - double pixelGreen = pixels[x, y].G; - double pixelBlue = pixels[x, y].B; - double pixelAlpha = pixels[x, y].A; + int bufferSize = strideWidth * scanHeight; + byte[] pixelBuffer = new byte[bufferSize]; + byte[] resultBuffer = new byte[bufferSize]; - pixelBuffer[byteOffset] = (byte)pixelBlue; - pixelBuffer[byteOffset + 1] = (byte)pixelGreen; - pixelBuffer[byteOffset + 2] = (byte)pixelRed; - pixelBuffer[byteOffset + 3] = (byte)pixelAlpha; - } - } - - Marshal.Copy(pixelBuffer, 0, resultData.Scan0, pixelBuffer.Length); - resultBitmap.UnlockBits(resultData); - - return resultBitmap; - } + Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); + sourceBitmap.UnlockBits(sourceData); - /// - /// Processes the given kernel to produce an array of pixels representing a bitmap. - /// - /// The raw pixels of the image to blur - /// The Gaussian kernel to use when performing the method - /// An array of pixels representing the bitmap. - public Pixel[,] ProcessKernel(Pixel[,] pixels, double[,] kernel) - { - int width = pixels.GetLength(0); - int height = pixels.GetLength(1); int kernelLength = kernel.GetLength(0); int radius = kernelLength >> 1; int kernelSize = kernelLength * kernelLength; - Pixel[,] result = new Pixel[width, height]; // For each line for (int y = 0; y < height; y++) @@ -367,6 +298,9 @@ namespace ImageProcessor.Imaging double green; double red = green = blue = alpha = divider = processedKernelSize = 0; + // The location of the pixel bytes. + int byteOffset = (y * strideWidth) + (x * 4); + // For each kernel row for (int i = 0; i < kernelLength; i++) { @@ -399,15 +333,19 @@ namespace ImageProcessor.Imaging if (offsetX < width) { - double k = kernel[i, j]; - Pixel pixel = pixels[offsetX, offsetY]; + int calcOffset = (offsetX * 4) + (offsetY * sourceData.Stride); + byte sourceBlue = pixelBuffer[calcOffset]; + byte sourceGreen = pixelBuffer[calcOffset + 1]; + byte sourceRed = pixelBuffer[calcOffset + 2]; + byte sourceAlpha = pixelBuffer[calcOffset + 3]; + double k = kernel[i, j]; divider += k; - red += k * pixel.R; - green += k * pixel.G; - blue += k * pixel.B; - alpha += k * pixel.A; + red += k * sourceRed; + green += k * sourceGreen; + blue += k * sourceBlue; + alpha += k * sourceAlpha; processedKernelSize++; } @@ -445,14 +383,24 @@ namespace ImageProcessor.Imaging blue += this.Threshold; alpha += this.Threshold; - result[x, y].R = (byte)((red > 255) ? 255 : ((red < 0) ? 0 : red)); - result[x, y].G = (byte)((green > 255) ? 255 : ((green < 0) ? 0 : green)); - result[x, y].B = (byte)((blue > 255) ? 255 : ((blue < 0) ? 0 : blue)); - result[x, y].A = (byte)((alpha > 255) ? 255 : ((alpha < 0) ? 0 : alpha)); + resultBuffer[byteOffset] = (byte)((blue > 255) ? 255 : ((blue < 0) ? 0 : blue)); + resultBuffer[byteOffset + 1] = (byte)((green > 255) ? 255 : ((green < 0) ? 0 : green)); + resultBuffer[byteOffset + 2] = (byte)((red > 255) ? 255 : ((red < 0) ? 0 : red)); + resultBuffer[byteOffset + 3] = (byte)((alpha > 255) ? 255 : ((alpha < 0) ? 0 : alpha)); } } - return result; + Bitmap resultBitmap = new Bitmap(width, height); + + BitmapData resultData = resultBitmap.LockBits( + new Rectangle(0, 0, width, height), + ImageLockMode.WriteOnly, + PixelFormat.Format32bppArgb); + + Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); + resultBitmap.UnlockBits(resultData); + + return resultBitmap; } #region Private diff --git a/src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs b/src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs index 784370ccb3..fd54cef225 100644 --- a/src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs +++ b/src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs @@ -1,19 +1,18 @@ -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // -// Copyright (c) James South. -// Licensed under the Apache License, Version 2.0. +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. // -// ----------------------------------------------------------------------- +// +// A list of available color matrices to apply to an image. +// +// -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Imaging.Filters { #region Using - using System; - using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; - using System.Linq; - using System.Text; - using System.Drawing.Imaging; + using System.Drawing.Imaging; #endregion /// @@ -175,5 +174,46 @@ namespace ImageProcessor.Imaging.Filters }); } } + + /// + /// Gets for generating the high pass + /// on the comic book filter. + /// + internal static ColorMatrix ComicHigh + { + get + { + return new ColorMatrix( + new float[][] + { + new float[] { 2, -0.5f, -0.5f, 0, 0 }, + new float[] { -0.5f, 2, -0.5f, 0, 0 }, + new float[] { -0.5f, -0.5f, 2, 0, 0 }, + new float[] { 0, 0, 0, 1, 0 }, + new float[] { 0, 0, 0, 0, 1 } + }); + } + } + + /// + /// Gets for generating the low pass + /// on the comic book filter. + /// + internal static ColorMatrix ComicLow + { + get + { + return new ColorMatrix( + new float[][] + { + new float[] { 1, 0, 0, 0, 0 }, + new float[] { 0, 1, 0, 0, 0 }, + new float[] { 0, 0, 1, 0, 0 }, + new float[] { 0, 0, 0, 1, 0 }, + new float[] { .075f, .075f, .075f, 0, 1 } + }); + } + } + } } diff --git a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs index 5cdf120763..d4506969c0 100644 --- a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs @@ -50,13 +50,13 @@ namespace ImageProcessor.Imaging.Filters /// Alpha = 3 } - + /// /// Gets the for this filter instance. /// public ColorMatrix Matrix { - get { return ColorMatrixes.LoSatch; } + get { return ColorMatrixes.ComicLow; } } /// @@ -74,61 +74,80 @@ namespace ImageProcessor.Imaging.Filters public Image TransformImage(ImageFactory factory, Image image, Image newImage) { // Bitmaps for comic pattern - Bitmap hisatchBitmap = null; + Bitmap highBitmap = null; + Bitmap lowBitmap = null; Bitmap patternBitmap = null; try { - using (Graphics graphics = Graphics.FromImage(newImage)) + using (ImageAttributes attributes = new ImageAttributes()) { - using (ImageAttributes attributes = new ImageAttributes()) - { - attributes.SetColorMatrix(this.Matrix); + Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); - Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); + attributes.SetColorMatrix(ColorMatrixes.ComicHigh); - // Set the attributes to LoSatch and draw the image. - graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); + // Draw the image with the high comic colormatrix. + highBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); - // Create a bitmap for overlaying. - hisatchBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + // Apply a oil painting filter to the image. + highBitmap = OilPaintFilter((Bitmap)image, 3, 5); - // Set the color matrix - attributes.SetColorMatrix(ColorMatrixes.HiSatch); + using (Graphics graphics = Graphics.FromImage(highBitmap)) + { + graphics.DrawImage(highBitmap, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); + } - // Draw the image with the hisatch colormatrix. - using (var g = Graphics.FromImage(hisatchBitmap)) - { - g.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); - } + // Create a bitmap for overlaying. + lowBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + + // Set the color matrix + attributes.SetColorMatrix(this.Matrix); + + // Draw the image with the losatch colormatrix. + using (Graphics graphics = Graphics.FromImage(lowBitmap)) + { + graphics.DrawImage(highBitmap, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); + } - // We need to create a new image now with the hi saturation colormatrix and a pattern mask to paint it - // onto the other image with. - patternBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); + // 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); - // Create the pattern mask. - using (var g = Graphics.FromImage(patternBitmap)) + // Create the pattern mask. + using (Graphics graphics = Graphics.FromImage(patternBitmap)) + { + graphics.Clear(Color.Black); + graphics.SmoothingMode = SmoothingMode.HighQuality; + + for (int y = 0; y < image.Height; y += 8) { - g.Clear(Color.Black); - g.SmoothingMode = SmoothingMode.HighQuality; - for (var y = 0; y < image.Height; y += 10) + for (int x = 0; x < image.Width; x += 4) { - for (var x = 0; x < image.Width; x += 6) - { - g.FillEllipse(Brushes.White, x, y, 4, 4); - g.FillEllipse(Brushes.White, x + 3, y + 5, 4, 4); - } + graphics.FillEllipse(Brushes.White, x, y, 3, 3); + graphics.FillEllipse(Brushes.White, x + 2, y + 4, 3, 3); } } + } - // Transfer the alpha channel from the mask to the high saturation image. - TransferOneArgbChannelFromOneBitmapToAnother(patternBitmap, hisatchBitmap, ChannelArgb.Blue, ChannelArgb.Alpha); + // Transfer the alpha channel from the mask to the high saturation image. + TransferOneArgbChannelFromOneBitmapToAnother(patternBitmap, lowBitmap, ChannelArgb.Blue, ChannelArgb.Alpha); + using (Graphics graphics = Graphics.FromImage(newImage)) + { // Overlay the image. - graphics.DrawImage(hisatchBitmap, 0, 0); + graphics.DrawImage(highBitmap, 0, 0); + graphics.DrawImage(lowBitmap, 0, 0); + + // Draw an edge around the image. + using (Pen blackPen = new Pen(Color.Black)) + { + blackPen.Width = 4; + graphics.DrawRectangle(blackPen, rectangle); + } // Dispose of the other images - hisatchBitmap.Dispose(); + highBitmap.Dispose(); + lowBitmap.Dispose(); patternBitmap.Dispose(); } } @@ -144,9 +163,14 @@ namespace ImageProcessor.Imaging.Filters newImage.Dispose(); } - if (hisatchBitmap != null) + if (highBitmap != null) { - hisatchBitmap.Dispose(); + highBitmap.Dispose(); + } + + if (lowBitmap != null) + { + lowBitmap.Dispose(); } if (patternBitmap != null) @@ -158,6 +182,335 @@ namespace ImageProcessor.Imaging.Filters return image; } + /// + /// Applies an oil paint filter. + /// TODO: Move this to another class and add to the factory + /// + /// + /// The source bitmap. + /// + /// + /// The levels. + /// + /// + /// The filter size. + /// + /// + /// The . + /// + private static Bitmap OilPaintFilter(Bitmap sourceBitmap, int levels, int filterSize) + { + int width = sourceBitmap.Width; + int height = sourceBitmap.Height; + + BitmapData sourceData = sourceBitmap.LockBits( + new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb); + + int strideWidth = sourceData.Stride; + int scanHeight = sourceData.Height; + + int bufferSize = strideWidth * scanHeight; + byte[] pixelBuffer = new byte[bufferSize]; + byte[] resultBuffer = new byte[bufferSize]; + + Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); + sourceBitmap.UnlockBits(sourceData); + + levels = levels - 1; + + int radius = filterSize >> 1; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int maxIntensity = 0; + int maxIndex = 0; + int[] intensityBin = new int[levels + 1]; + int[] blueBin = new int[levels + 1]; + int[] greenBin = new int[levels + 1]; + int[] redBin = new int[levels + 1]; + + int byteOffset = (y * strideWidth) + (x * 4); + + for (int i = 0; i <= radius; i++) + { + int ir = i - radius; + int offsetY = y + ir; + + // Skip the current row + if (offsetY < 0) + { + continue; + } + + // Outwith the current bounds so break. + if (offsetY >= height) + { + break; + } + + for (int j = 0; j <= radius; j++) + { + int jr = j - radius; + int offsetX = x + jr; + + // Skip the column + if (offsetX < 0) + { + continue; + } + + if (offsetX < width) + { + int calcOffset = (offsetX * 4) + (offsetY * sourceData.Stride); + + byte sourceBlue = pixelBuffer[calcOffset]; + byte sourceGreen = pixelBuffer[calcOffset + 1]; + byte sourceRed = pixelBuffer[calcOffset + 2]; + + int currentIntensity = (int)Math.Round(((sourceBlue + sourceGreen + sourceRed) / 3.0 * levels) / 255.0); + + intensityBin[currentIntensity] += 1; + blueBin[currentIntensity] += sourceBlue; + greenBin[currentIntensity] += sourceGreen; + redBin[currentIntensity] += sourceRed; + + if (intensityBin[currentIntensity] > maxIntensity) + { + maxIntensity = intensityBin[currentIntensity]; + maxIndex = currentIntensity; + } + } + } + } + + double blue = Math.Abs(blueBin[maxIndex] / maxIntensity); + double green = Math.Abs(greenBin[maxIndex] / maxIntensity); + double red = Math.Abs(redBin[maxIndex] / maxIntensity); + + blue = blue > 255 ? 255 : (blue < 0 ? 0 : blue); + green = green > 255 ? 255 : (green < 0 ? 0 : green); + red = red > 255 ? 255 : (red < 0 ? 0 : red); + + resultBuffer[byteOffset] = (byte)blue; + resultBuffer[byteOffset + 1] = (byte)green; + resultBuffer[byteOffset + 2] = (byte)red; + resultBuffer[byteOffset + 3] = 255; + } + } + + Bitmap resultBitmap = new Bitmap(width, height); + + BitmapData resultData = resultBitmap.LockBits( + new Rectangle(0, 0, width, height), + ImageLockMode.WriteOnly, + PixelFormat.Format32bppArgb); + + Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); + resultBitmap.UnlockBits(resultData); + + return resultBitmap; + } + + /// + /// Detects and draws edges. + /// TODO: Move this to another class and do move edge detection. + /// + /// + /// The source bitmap. + /// + /// + /// The threshold. + /// + /// + /// The . + /// + private static Bitmap DrawEdges(Bitmap sourceBitmap, byte threshold = 0) + { + Color color = Color.Black; + int width = sourceBitmap.Width; + int height = sourceBitmap.Height; + + BitmapData sourceData = sourceBitmap.LockBits( + new Rectangle(0, 0, width, height), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb); + + int strideWidth = sourceData.Stride; + int scanHeight = sourceData.Height; + + int bufferSize = strideWidth * scanHeight; + byte[] pixelBuffer = new byte[bufferSize]; + byte[] resultBuffer = new byte[bufferSize]; + + Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); + + sourceBitmap.UnlockBits(sourceData); + + for (int offsetY = 1; offsetY < height - 1; offsetY++) + { + for (int offsetX = 1; offsetX < width - 1; offsetX++) + { + int byteOffset = (offsetY * strideWidth) + (offsetX * 4); + + int blueGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + + blueGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + byteOffset++; + + int greenGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + + greenGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + byteOffset++; + + int redGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + + redGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + bool exceedsThreshold; + if (blueGradient + greenGradient + redGradient > threshold) + { + exceedsThreshold = true; + } + else + { + byteOffset -= 2; + + blueGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + byteOffset++; + + greenGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + byteOffset++; + + redGradient = Math.Abs(pixelBuffer[byteOffset - 4] - pixelBuffer[byteOffset + 4]); + + if (blueGradient + greenGradient + redGradient > threshold) + { + exceedsThreshold = true; + } + else + { + byteOffset -= 2; + + blueGradient = + Math.Abs(pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + byteOffset++; + + greenGradient = + Math.Abs(pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + byteOffset++; + + redGradient = + Math.Abs(pixelBuffer[byteOffset - strideWidth] - pixelBuffer[byteOffset + strideWidth]); + + if (blueGradient + greenGradient + redGradient > threshold) + { + exceedsThreshold = true; + } + else + { + byteOffset -= 2; + + blueGradient = + Math.Abs( + pixelBuffer[byteOffset - 4 - strideWidth] + - pixelBuffer[byteOffset + 4 + strideWidth]); + + blueGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth + 4] + - pixelBuffer[byteOffset + strideWidth - 4]); + + byteOffset++; + + greenGradient = + Math.Abs( + pixelBuffer[byteOffset - 4 - strideWidth] + - pixelBuffer[byteOffset + 4 + strideWidth]); + + greenGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth + 4] + - pixelBuffer[byteOffset + strideWidth - 4]); + + byteOffset++; + + redGradient = + Math.Abs( + pixelBuffer[byteOffset - 4 - strideWidth] + - pixelBuffer[byteOffset + 4 + strideWidth]); + + redGradient += + Math.Abs( + pixelBuffer[byteOffset - strideWidth + 4] + - pixelBuffer[byteOffset + strideWidth - 4]); + + exceedsThreshold = blueGradient + greenGradient + redGradient > threshold; + } + } + } + + byteOffset -= 2; + + double blue; + double red; + double green; + double alpha; + if (exceedsThreshold) + { + blue = color.B; // 0; + green = color.G; // 0; + red = color.R; // 0; + alpha = 255; + } + else + { + // These would normally be used to transfer the correct value accross. + // blue = pixelBuffer[byteOffset]; + // green = pixelBuffer[byteOffset + 1]; + // red = pixelBuffer[byteOffset + 2]; + blue = 255; + green = 255; + red = 255; + alpha = 0; + } + + blue = blue > 255 ? 255 : (blue < 0 ? 0 : blue); + green = green > 255 ? 255 : (green < 0 ? 0 : green); + red = red > 255 ? 255 : (red < 0 ? 0 : red); + resultBuffer[byteOffset] = (byte)blue; + resultBuffer[byteOffset + 1] = (byte)green; + resultBuffer[byteOffset + 2] = (byte)red; + resultBuffer[byteOffset + 3] = (byte)alpha; + } + } + + Bitmap resultBitmap = new Bitmap(width, height); + + BitmapData resultData = resultBitmap.LockBits( + new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), + ImageLockMode.WriteOnly, + PixelFormat.Format32bppArgb); + + Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); + + resultBitmap.UnlockBits(resultData); + return resultBitmap; + } + /// /// Transfers a single ARGB channel from one image to another. /// @@ -211,6 +564,7 @@ namespace ImageProcessor.Imaging.Filters for (int i = rectangle.Height * rectangle.Width; i > 0; i--) { + // Copy the alpha values across. destinationRgbValues[d] = sourceRgbValues[s]; d += 4; s += 4; @@ -223,4 +577,4 @@ namespace ImageProcessor.Imaging.Filters destination.UnlockBits(bitmapDataDestination); } } -} +} \ No newline at end of file diff --git a/src/ImageProcessor/Imaging/ResizeLayer.cs b/src/ImageProcessor/Imaging/ResizeLayer.cs index c35a4d3d3a..02c636b3d0 100644 --- a/src/ImageProcessor/Imaging/ResizeLayer.cs +++ b/src/ImageProcessor/Imaging/ResizeLayer.cs @@ -26,64 +26,29 @@ namespace ImageProcessor.Imaging /// /// The containing the width and height to set the image to. /// - public ResizeLayer(Size size) - { - this.Size = size; - this.ResizeMode = ResizeMode.Pad; - this.AnchorPosition = AnchorPosition.Center; - this.BackgroundColor = Color.Transparent; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The containing the width and height to set the image to. - /// - /// - /// The to apply to resized image. - /// - public ResizeLayer(Size size, ResizeMode resizeMode) - { - this.Size = size; - this.ResizeMode = resizeMode; - this.AnchorPosition = AnchorPosition.Center; - this.BackgroundColor = Color.Transparent; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The containing the width and height to set the image to. - /// - /// - /// The to apply to resized image. - /// - public ResizeLayer(Size size, AnchorPosition anchorPosition) - { - this.Size = size; - this.AnchorPosition = anchorPosition; - this.ResizeMode = ResizeMode.Pad; - this.BackgroundColor = Color.Transparent; - } - - /// - /// Initializes a new instance of the class. - /// /// /// The to set as the background color. - /// Used for image formats that do not support transparency + /// Used for image formats that do not support transparency (Default transparent) /// /// - /// The resize mode to apply to resized image. + /// The resize mode to apply to resized image. (Default ResizeMode.Pad) /// /// - /// The to apply to resized image. + /// The to apply to resized image. (Default AnchorPosition.Center) + /// + /// + /// Whether to allow up-scaling of images. (Default true) /// - public ResizeLayer(Color backgroundColor, ResizeMode resizeMode = ResizeMode.Pad, AnchorPosition anchorPosition = AnchorPosition.Center) + public ResizeLayer( + Size size, + Color? backgroundColor = null, + ResizeMode resizeMode = ResizeMode.Pad, + AnchorPosition anchorPosition = AnchorPosition.Center, + bool upscale = true) { - this.BackgroundColor = backgroundColor; + this.Size = size; + this.Upscale = upscale; + this.BackgroundColor = backgroundColor ?? Color.Transparent; this.ResizeMode = resizeMode; this.AnchorPosition = anchorPosition; } @@ -109,6 +74,11 @@ namespace ImageProcessor.Imaging /// Gets or sets the anchor position. /// public AnchorPosition AnchorPosition { get; set; } + + /// + /// Gets or sets a value indicating whether to allow up-scaling of images. + /// + public bool Upscale { get; set; } #endregion /// @@ -135,7 +105,8 @@ namespace ImageProcessor.Imaging return this.Size == resizeLayer.Size && this.ResizeMode == resizeLayer.ResizeMode && this.AnchorPosition == resizeLayer.AnchorPosition - && this.BackgroundColor == resizeLayer.BackgroundColor; + && this.BackgroundColor == resizeLayer.BackgroundColor + && this.Upscale == resizeLayer.Upscale; } /// @@ -146,7 +117,11 @@ namespace ImageProcessor.Imaging /// public override int GetHashCode() { - return this.Size.GetHashCode() + this.ResizeMode.GetHashCode() + this.AnchorPosition.GetHashCode() + this.BackgroundColor.GetHashCode(); + return this.Size.GetHashCode() + + this.ResizeMode.GetHashCode() + + this.AnchorPosition.GetHashCode() + + this.BackgroundColor.GetHashCode() + + this.Upscale.GetHashCode(); } } } diff --git a/src/ImageProcessor/Processors/Filter.cs b/src/ImageProcessor/Processors/Filter.cs index 0cee24c0da..cfdd05cb8b 100644 --- a/src/ImageProcessor/Processors/Filter.cs +++ b/src/ImageProcessor/Processors/Filter.cs @@ -120,6 +120,7 @@ namespace ImageProcessor.Processors try { // Don't use an object initializer here. + // ReSharper disable once UseObjectOrCollectionInitializer newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb); newImage.Tag = image.Tag; diff --git a/src/ImageProcessor/Processors/GaussianBlur.cs b/src/ImageProcessor/Processors/GaussianBlur.cs index 7da860121c..d6d697508c 100644 --- a/src/ImageProcessor/Processors/GaussianBlur.cs +++ b/src/ImageProcessor/Processors/GaussianBlur.cs @@ -139,10 +139,8 @@ namespace ImageProcessor.Processors GaussianLayer gaussianLayer = (GaussianLayer)this.DynamicParameter; Convolution convolution = new Convolution(gaussianLayer.Sigma) { Threshold = gaussianLayer.Threshold }; - Pixel[,] pixels = convolution.BitmapToPixels(newImage); double[,] kernel = convolution.CreateGuassianBlurFilter(gaussianLayer.Size); - pixels = convolution.ProcessKernel(pixels, kernel); - newImage = convolution.PixelsToBitmap(pixels); + newImage = convolution.ProcessKernel(newImage, kernel); newImage.Tag = image.Tag; image.Dispose(); @@ -194,9 +192,9 @@ namespace ImageProcessor.Processors /// private int ParseThreshold(string input) { + // ReSharper disable once LoopCanBeConvertedToQuery foreach (Match match in ThresholdRegex.Matches(input)) { - // split on text- return Convert.ToInt32(match.Value.Split('-')[1]); } @@ -215,9 +213,9 @@ namespace ImageProcessor.Processors /// private int ParseBlur(string input) { + // ReSharper disable once LoopCanBeConvertedToQuery foreach (Match match in BlurRegex.Matches(input)) { - // split on text- return Convert.ToInt32(match.Value.Split('=')[1]); } diff --git a/src/ImageProcessor/Processors/GaussianSharpen.cs b/src/ImageProcessor/Processors/GaussianSharpen.cs index eab7460a16..5bd4cacab4 100644 --- a/src/ImageProcessor/Processors/GaussianSharpen.cs +++ b/src/ImageProcessor/Processors/GaussianSharpen.cs @@ -138,10 +138,8 @@ namespace ImageProcessor.Processors GaussianLayer gaussianLayer = (GaussianLayer)this.DynamicParameter; Convolution convolution = new Convolution(gaussianLayer.Sigma) { Threshold = gaussianLayer.Threshold }; - Pixel[,] pixels = convolution.BitmapToPixels(newImage); double[,] kernel = convolution.CreateGuassianSharpenFilter(gaussianLayer.Size); - pixels = convolution.ProcessKernel(pixels, kernel); - newImage = convolution.PixelsToBitmap(pixels); + newImage = convolution.ProcessKernel(newImage, kernel); newImage.Tag = image.Tag; image.Dispose(); @@ -193,9 +191,9 @@ namespace ImageProcessor.Processors /// private int ParseThreshold(string input) { + // ReSharper disable once LoopCanBeConvertedToQuery foreach (Match match in ThresholdRegex.Matches(input)) { - // split on text- return Convert.ToInt32(match.Value.Split('-')[1]); } @@ -214,9 +212,9 @@ namespace ImageProcessor.Processors /// private int ParseSharpen(string input) { + // ReSharper disable once LoopCanBeConvertedToQuery foreach (Match match in SharpenRegex.Matches(input)) { - // split on text- return Convert.ToInt32(match.Value.Split('=')[1]); } diff --git a/src/ImageProcessor/Processors/Resize.cs b/src/ImageProcessor/Processors/Resize.cs index 7fac2cc420..d0ba5539a8 100644 --- a/src/ImageProcessor/Processors/Resize.cs +++ b/src/ImageProcessor/Processors/Resize.cs @@ -32,7 +32,7 @@ namespace ImageProcessor.Processors /// /// The regular expression to search strings for. /// - private static readonly Regex QueryRegex = new Regex(@"((width|height)=\d+)|(mode=(pad|stretch|crop|max))|(anchor=(top|bottom|left|right|center))|(bgcolor=([0-9a-fA-F]{3}){1,2})", RegexOptions.Compiled); + private static readonly Regex QueryRegex = new Regex(@"((width|height)=\d+)|(mode=(pad|stretch|crop|max))|(anchor=(top|bottom|left|right|center))|(bgcolor=([0-9a-fA-F]{3}){1,2})|(upscale=false)", RegexOptions.Compiled); /// /// The regular expression to search strings for the size attribute. @@ -54,6 +54,10 @@ namespace ImageProcessor.Processors /// private static readonly Regex ColorRegex = new Regex(@"bgcolor=([0-9a-fA-F]{3}){1,2}", RegexOptions.Compiled); + /// + /// The regular expression to search strings for the upscale attribute. + /// + private static readonly Regex UpscaleRegex = new Regex(@"upscale=false", RegexOptions.Compiled); #region IGraphicsProcessor Members /// /// Gets the regular expression to search strings for. @@ -136,7 +140,8 @@ namespace ImageProcessor.Processors { ResizeMode = this.ParseMode(toParse), AnchorPosition = this.ParsePosition(toParse), - BackgroundColor = this.ParseColor(toParse) + BackgroundColor = this.ParseColor(toParse), + Upscale = !UpscaleRegex.IsMatch(toParse) }; this.DynamicParameter = resizeLayer; @@ -160,13 +165,14 @@ namespace ImageProcessor.Processors ResizeMode mode = this.DynamicParameter.ResizeMode; AnchorPosition anchor = this.DynamicParameter.AnchorPosition; Color backgroundColor = this.DynamicParameter.BackgroundColor; + bool upscale = this.DynamicParameter.Upscale; int defaultMaxWidth; int defaultMaxHeight; int.TryParse(this.Settings["MaxWidth"], out defaultMaxWidth); int.TryParse(this.Settings["MaxHeight"], out defaultMaxHeight); - return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight, backgroundColor, mode, anchor); + return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight, backgroundColor, mode, anchor, upscale); } #endregion @@ -198,6 +204,9 @@ namespace ImageProcessor.Processors /// /// The anchor position to place the image at. /// + /// + /// Whether to allow up-scaling of images. (Default true) + /// /// /// The processed image from the current instance of the class. /// @@ -209,7 +218,8 @@ namespace ImageProcessor.Processors int defaultMaxHeight, Color backgroundColor, ResizeMode resizeMode = ResizeMode.Pad, - AnchorPosition anchorPosition = AnchorPosition.Center) + AnchorPosition anchorPosition = AnchorPosition.Center, + bool upscale = true) { Bitmap newImage = null; Image image = factory.Image; @@ -332,6 +342,12 @@ namespace ImageProcessor.Processors if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight) { + // Exit if upscaling is not allowed. + if ((width > sourceWidth || height > sourceHeight) && upscale == false && resizeMode != ResizeMode.Stretch) + { + return image; + } + // Don't use an object initializer here. // ReSharper disable once UseObjectOrCollectionInitializer newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb); diff --git a/src/TestWebsites/NET4/Images/Thumbs.db.REMOVED.git-id b/src/TestWebsites/NET4/Images/Thumbs.db.REMOVED.git-id index 3619925b06..32de55cbda 100644 --- a/src/TestWebsites/NET4/Images/Thumbs.db.REMOVED.git-id +++ b/src/TestWebsites/NET4/Images/Thumbs.db.REMOVED.git-id @@ -1 +1 @@ -32c1c68dd25fc55293b1a21c1ea25002c53f984b \ No newline at end of file +1d78931ad90a644551671f9b1252e4e772f2493b \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/Penguins-200.jpg b/src/TestWebsites/NET45/Test_Website_NET45/Images/Penguins-200.jpg new file mode 100644 index 0000000000000000000000000000000000000000..364d16a2b6ea14dfcc1f2dcfafe72a91b396e504 GIT binary patch literal 10119 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 literal 0 HcmV?d00001 diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/Thumbs.db.REMOVED.git-id b/src/TestWebsites/NET45/Test_Website_NET45/Images/Thumbs.db.REMOVED.git-id new file mode 100644 index 0000000000..60a8946afe --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_NET45/Images/Thumbs.db.REMOVED.git-id @@ -0,0 +1 @@ +5a5eaebf9a5eafe87321a87bf497baf7e2152653 \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/emma.jpg b/src/TestWebsites/NET45/Test_Website_NET45/Images/emma.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7857041909364b2584fc673130d3114dda8a8d97 GIT binary patch literal 29617 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 XZ4QcfVByHk>esL8Q!}Ff`|$q&6as+> literal 0 HcmV?d00001 diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/MSwanson - Wide Large - Rock 02.jpg.REMOVED.git-id b/src/TestWebsites/NET45/Test_Website_NET45/Images/rocks.jpg.REMOVED.git-id similarity index 100% rename from src/TestWebsites/NET45/Test_Website_NET45/Images/MSwanson - Wide Large - Rock 02.jpg.REMOVED.git-id rename to src/TestWebsites/NET45/Test_Website_NET45/Images/rocks.jpg.REMOVED.git-id diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/thor.jpg.REMOVED.git-id b/src/TestWebsites/NET45/Test_Website_NET45/Images/thor.jpg.REMOVED.git-id new file mode 100644 index 0000000000..2b94932d0a --- /dev/null +++ b/src/TestWebsites/NET45/Test_Website_NET45/Images/thor.jpg.REMOVED.git-id @@ -0,0 +1 @@ +4087bfc9fb25acb1bb13a15478f74e088f617934 \ No newline at end of file diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Images/udendørs-374.jpg b/src/TestWebsites/NET45/Test_Website_NET45/Images/udendørs-374.jpg new file mode 100644 index 0000000000000000000000000000000000000000..00c466136f6656fbb14e7c25ce067d8dfad43a7d GIT binary patch literal 20944 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

pWVI?4k-j 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 z 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 + + + + diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml index 7bc0464b9b..6572d1734d 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml +++ b/src/TestWebsites/NET45/Test_Website_NET45/Views/Home/Index.cshtml @@ -8,8 +8,6 @@

Resized

- -

Foreign language test.

@@ -53,6 +51,17 @@
+
+
+

Resize Max - No Upscale

+
+ +
+
+ +
+
+

Resize Stretch

@@ -160,9 +169,19 @@
+
+
+
+

Gaussian Blur

+ +
+
+

Gaussian Sharpen

+ +
+
+
- -

Color Profiles

@*
diff --git a/src/TestWebsites/NET45/Test_Website_NET45/Web.config b/src/TestWebsites/NET45/Test_Website_NET45/Web.config index 70a09ab843..001fd564ff 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/Web.config +++ b/src/TestWebsites/NET45/Test_Website_NET45/Web.config @@ -18,7 +18,7 @@ - +