private dynamic ResizeImage(dynamic arg) { var file = Path.Combine(this.RootPath, (string)arg.path); if (File.Exists(file) == false) { return(404); } if (this.Request.Url.Query == string.Empty) { return(400); } var parameter = new ImageResizeModule.ImageFiltrationParameters(this.Context, file); var parameterKey = parameter.GetHashCode().ToString(); var key = file + parameterKey; string resizeRelativePath; if (_FileList.TryGetValue(key, out resizeRelativePath) == true) { return(this.Response.AsRedirect(resizeRelativePath, Nancy.Responses.RedirectResponse.RedirectType.Permanent)); } resizeRelativePath = "site/imageresize/" + (string)arg.path + "/" + parameterKey + Path.GetExtension(file); var rootPath = this.RootPath; var resizeDirectory = Path.Combine(rootPath, "Site", "imageresize", (string)arg.path); Directory.CreateDirectory(resizeDirectory); var resizeFile = Path.Combine(rootPath, resizeRelativePath); lock (resizeFile) { if (File.Exists(resizeFile) == true) { _FileList[key] = "/" + resizeRelativePath; return(this.Response.AsRedirect("/" + resizeRelativePath, Nancy.Responses.RedirectResponse.RedirectType.Permanent)); } if (Directory.GetFiles(resizeDirectory).Length + 1 > MAX_PER_FILE) { return(400); } var result = ImageResizeModule.ResizeAndFilterImage(file, parameter); using (var resized = File.OpenWrite(resizeFile)) { result.Output.CopyTo(resized); } _FileList[key] = "/" + resizeRelativePath; return(this.Response.AsRedirect("/" + resizeRelativePath, Nancy.Responses.RedirectResponse.RedirectType.Permanent)); } }
/// <summary> /// Resize the image without using disk cache /// </summary> /// <param name="arg"></param> /// <returns></returns> private dynamic ResizeImage_NoCache(dynamic arg) { var file = Path.Combine(this.RootPath, (string)arg.path); if (File.Exists(file) == false) { return(404); } var parameter = new ImageResizeModule.ImageFiltrationParameters(arg, file); var parameterKey = parameter.GetHashCode().ToString(); HashSet <string> set; if (_AttackPrevention.TryGetValue(file, out set) == false) { set = new HashSet <string>(); _AttackPrevention.Add(file, set); } // this file contains too much unique parameter request if (set.Contains(parameterKey) == false && set.Count > MAX_PER_FILE) { return(404); } set.Add(parameterKey); var cacheKey = file + "&&" + parameter.GetHashCode(); var result = MemoryCache.Default.Get(cacheKey) as ResizeResult; if (result == null) { var resizeResult = ImageResizeModule.ResizeAndFilterImage(file, parameter); result = resizeResult; MemoryCache.Default.Add(cacheKey, result, DateTimeOffset.Now.AddMinutes(10)); } var response = new Response(); response.ContentType = result.ContentType; response.Contents = (s) => { result.Output.Position = 0; result.Output.CopyTo(s); }; return(response); }
/// <summary> /// Get Resized Image /// </summary> /// <param name="width">Desired with of the image - will be set to actual image width</param> /// <param name="height">Desired height of the image - will be set to actual image height</param> /// <returns></returns> public static ResizeResult ResizeAndFilterImage(string file, ImageFiltrationParameters parameters) { var result = new ResizeResult(); result.Output = new MemoryStream(); result.SourceFile = file; // make sure we have no problem with file lock var source = File.ReadAllBytes(file); using (var ms = new MemoryStream(source)) using (var b = Bitmap.FromStream(ms)) { bool isPNG = b.RawFormat.Equals(ImageFormat.Png); bool isJPEG = b.RawFormat.Equals(ImageFormat.Jpeg); parameters.Validate(b); Bitmap newBitMap = null; #region Resize if (parameters.IsProcessResize == true) { newBitMap = new Bitmap(parameters.TargetWidth, parameters.TargetHeight); var g = Graphics.FromImage(newBitMap); if (isPNG == true) { g.Clear(Color.Transparent); } else { g.Clear(Color.White); } ImageResizeModule.FillBackground(b, g, parameters); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; g.DrawImage(b, parameters.ImageOffsetAndSize.Left, parameters.ImageOffsetAndSize.Top, parameters.ImageOffsetAndSize.Width, parameters.ImageOffsetAndSize.Height); g.Dispose(); } else { newBitMap = (Bitmap)b; } #endregion #region Filtration if (parameters.Filters != null) { foreach (var filter in parameters.Filters) { if (filter.ToLower() == "grayscale") { var filtered = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.Y.Apply(newBitMap); newBitMap.Dispose(); newBitMap = filtered; continue; } var name = " AForge.Imaging.Filters." + filter; var filterType = Assembly.GetAssembly(typeof(AForge.Imaging.Filters.BaseFilter)).GetType(name, false, true); if (filterType == null || filterType.IsAbstract || filterType.IsInterface || !filterType.IsPublic) { throw new InvalidOperationException("Filter name " + filter + " is not valid"); } try { var instance = Activator.CreateInstance(filterType) as AForge.Imaging.Filters.IFilter; if (instance == null) { throw new InvalidOperationException("Filter name " + filter + " is not valid"); } var filtered = instance.Apply(newBitMap); newBitMap.Dispose(); newBitMap = filtered; } catch (Exception ex) { throw new InvalidOperationException("Filter name " + filter + " is not valid", ex); } } } #endregion if (isJPEG == true) { var ep = new EncoderParameters(); ep.Param[0] = new EncoderParameter(Encoder.Quality, 95L); var ici = (from item in ImageCodecInfo.GetImageEncoders() where item.MimeType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase) select item).FirstOrDefault(); try { newBitMap.Save(result.Output, ici, ep); } catch (Exception) { newBitMap.Save(result.Output, ImageFormat.Jpeg); } result.ContentType = "image/jpeg"; } else { result.ContentType = "image/png"; newBitMap.Save(result.Output, ImageFormat.Png); } newBitMap.Dispose(); } result.Output.Position = 0; return(result); }