/// <summary> /// Gets resizing options from query string /// </summary> /// <param name="queryString">The query string.</param> /// <returns>Resizing options</returns> private static ResizingOptions FromQueryString(NameValueCollection queryString) { var result = new ResizingOptions(); string str = queryString["w"]; if (!string.IsNullOrEmpty(str)) { result.Width = int.Parse(str); } str = queryString["h"]; if (!string.IsNullOrEmpty(str)) { result.Height = int.Parse(str); } str = queryString["mw"]; if (!string.IsNullOrEmpty(str)) { result.MaxWidth = int.Parse(str); } str = queryString["mh"]; if (!string.IsNullOrEmpty(str)) { result.MaxHeight = int.Parse(str); } str = queryString["q"]; if (!string.IsNullOrEmpty(str)) { result.QualityOverride = int.Parse(str); if (result.QualityOverride < 1) { result.QualityOverride = 1; } if (result.QualityOverride > 100) { result.QualityOverride = 100; } } ResizingAction resizingAction; string action = queryString["action"]; if (!action.IsNullOrEmpty() && Enum.TryParse(action, true, out resizingAction)) { result.ResizingAction = resizingAction; } else { result.ResizingAction = Media.ResizingAction.Stretch; } return(result); }
/// <exclude /> public string GetResizedImageUrl(string storeId, Guid mediaId, ResizingOptions resizingOptions) { IMediaFile file = GetFileById(storeId, mediaId); if (file == null) { return null; } string pathToFile = UrlUtils.Combine(file.FolderPath, file.FileName); pathToFile = RemoveForbiddenCharactersAndNormalize(pathToFile); // IIS6 doesn't have wildcard mapping by default, so removing image extension if running in "classic" app pool if (!HttpRuntime.UsingIntegratedPipeline) { int dotOffset = pathToFile.IndexOf(".", StringComparison.Ordinal); if (dotOffset >= 0) { pathToFile = pathToFile.Substring(0, dotOffset); } } string mediaStore = string.Empty; if (!storeId.Equals(DefaultMediaStore, StringComparison.InvariantCultureIgnoreCase)) { mediaStore = storeId + "/"; } var url = new UrlBuilder(UrlUtils.PublicRootPath + "/media/" + mediaStore + /* UrlUtils.CompressGuid(*/ mediaId /*)*/) { PathInfo = file.LastWriteTime != null ? "/" + GetDateTimeHash(file.LastWriteTime.Value.ToUniversalTime()) : string.Empty }; if (pathToFile.Length > 0) { url.PathInfo += pathToFile; } if (resizingOptions != null && !resizingOptions.IsEmpty) { return url + "?" + resizingOptions; } return url.ToString(); }
/// <summary> /// Returns a media url. /// </summary> /// <param name="keyPath">Image's KeyPath field value.</param> /// <param name="resizingOptions">The resizing options.</param> /// <returns></returns> public IHtmlString MediaUrl(string keyPath, ResizingOptions resizingOptions) { string relativeUrl = "~/media(" + keyPath + ")"; string absoluteUrl = VirtualPathUtility.ToAbsolute(relativeUrl); string queryString = resizingOptions.ToString(); if (!string.IsNullOrEmpty(queryString)) { absoluteUrl += "?" + queryString.Replace("&", "&"); } return _helper.Raw(absoluteUrl); }
/// <summary> /// Returns a media url. /// </summary> /// <param name="image">The image file.</param> /// <param name="resizingOptions">The resizing options.</param> /// <returns></returns> public IHtmlString MediaUrl(IImageFile image, ResizingOptions resizingOptions) { return MediaUrl(image.KeyPath, resizingOptions); }
/// <summary> /// Returns a media url. /// </summary> /// <param name="image">The image file.</param> /// <param name="resizingOptions">The resizing options.</param> /// <returns></returns> public IHtmlString MediaUrl(DataReference<IImageFile> image, ResizingOptions resizingOptions) { return MediaUrl((string) image.KeyValue, resizingOptions); }
/// <summary> /// Gets the resized image. /// </summary> /// <param name="httpServerUtility">An instance of <see cref="System.Web.HttpServerUtility" />.</param> /// <param name="file">The media file.</param> /// <param name="resizingOptions">The resizing options.</param> /// <param name="targetImageFormat">The target image format.</param> /// <returns>A full file path to a resized image; null if there's no need to resize the image</returns> public static string GetResizedImage(HttpServerUtility httpServerUtility, IMediaFile file, ResizingOptions resizingOptions, ImageFormat targetImageFormat) { Verify.ArgumentNotNull(file, "file"); Verify.That(ImageFormatIsSupported(targetImageFormat), "Unsupported image format '{0}'", targetImageFormat); if (_resizedImagesDirectoryPath == null) { _resizedImagesDirectoryPath = httpServerUtility.MapPath(ResizedImagesCacheDirectory); if (!C1Directory.Exists(_resizedImagesDirectoryPath)) { C1Directory.CreateDirectory(_resizedImagesDirectoryPath); } } string imageKey = file.CompositePath; bool isNativeProvider = file is FileSystemFileBase; string imageSizeCacheKey = "ShowMedia.ashx image size " + imageKey; Size? imageSize = HttpRuntime.Cache.Get(imageSizeCacheKey) as Size?; Bitmap bitmap = null; Stream fileStream = null; try { if (imageSize == null) { fileStream = file.GetReadStream(); Size calculatedSize; if (!ImageSizeReader.TryGetSize(fileStream, out calculatedSize)) { fileStream.Dispose(); fileStream = file.GetReadStream(); bitmap = new Bitmap(fileStream); calculatedSize = new Size { Width = bitmap.Width, Height = bitmap.Height }; } imageSize = calculatedSize; // We can provider cache dependency only for the native media provider var cacheDependency = isNativeProvider ? new CacheDependency((file as FileSystemFileBase).SystemPath) : null; HttpRuntime.Cache.Add(imageSizeCacheKey, imageSize, cacheDependency, DateTime.MaxValue, CacheExpirationTimeSpan, CacheItemPriority.Normal, null); } int newWidth, newHeight; bool centerCrop; bool needToResize = CalculateSize(imageSize.Value.Width, imageSize.Value.Height, resizingOptions, out newWidth, out newHeight, out centerCrop); needToResize = needToResize || resizingOptions.CustomQuality; if (!needToResize) { return null; } int filePathHash = imageKey.GetHashCode(); string centerCroppedString = centerCrop ? "c" : string.Empty; string fileExtension = _ImageFormat2Extension[targetImageFormat]; string resizedImageFileName = string.Format("{0}x{1}_{2}{3}_{4}.{5}", newWidth, newHeight, filePathHash, centerCroppedString, resizingOptions.Quality, fileExtension); string imageFullPath = Path.Combine(_resizedImagesDirectoryPath, resizedImageFileName); if (!C1File.Exists(imageFullPath) || C1File.GetLastWriteTime(imageFullPath) != file.LastWriteTime) { if (bitmap == null) { fileStream = file.GetReadStream(); bitmap = new Bitmap(fileStream); } ResizeImage(bitmap, imageFullPath, newWidth, newHeight, centerCrop, targetImageFormat, resizingOptions.Quality); if (file.LastWriteTime.HasValue) { C1File.SetLastWriteTime(imageFullPath, file.LastWriteTime.Value); } } return imageFullPath; } finally { if (bitmap != null) { bitmap.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } }
private static bool CalculateSize(int width, int height, ResizingOptions resizingOptions, out int newWidth, out int newHeight, out bool centerCrop) { // Can be refactored to use System.Drawing.Size class instead of (width & height). if (width == 0 || height == 0) { newHeight = newWidth = 0; centerCrop = false; return false; } Verify.ArgumentCondition(width > 0, "width", "Negative values aren't allowed"); Verify.ArgumentCondition(height > 0, "height", "Negative values aren't allowed"); centerCrop = false; // If both height and width are defined - we have "scalling" if (resizingOptions.Height != null && resizingOptions.Width != null) { newHeight = (int)resizingOptions.Height; newWidth = (int)resizingOptions.Width; // we do not allow scalling to a size, bigger than original one if (newHeight > height) { newHeight = height; } if (newWidth > width) { newWidth = width; } // If the target dimensions are bigger or the same size as of the image - no resizing is done if (newWidth == width && newHeight == height) { return false; } switch (resizingOptions.ResizingAction) { case ResizingAction.Stretch: // no additional logic break; case ResizingAction.Crop: centerCrop = true; break; case ResizingAction.Fit: case ResizingAction.Fill: // No float point division for better precision Int64 heightProportionArea = (Int64)newHeight * width; Int64 widthProportionArea = (Int64)newWidth * height; if (heightProportionArea == widthProportionArea) { break; } if ((heightProportionArea > widthProportionArea) // (newHeight / height) > (newWidth / width) ^ (resizingOptions.ResizingAction == ResizingAction.Fit)) { newWidth = (int)(heightProportionArea / height); // newWidth = width * (newHeight / height) } else { newHeight = (int)(widthProportionArea / width); // newHeight = height * (newWidth / width) } break; } return true; } newWidth = width; newHeight = height; // If image doesn't fit to bondaries "maxWidth X maxHeight", downsizing it int? maxWidth = resizingOptions.Width; if (resizingOptions.MaxWidth != null && (maxWidth == null || resizingOptions.MaxWidth < maxWidth)) { maxWidth = resizingOptions.MaxWidth; } int? maxHeight = resizingOptions.Height; if (resizingOptions.MaxHeight != null && (maxHeight == null || resizingOptions.MaxHeight < maxHeight)) { maxHeight = resizingOptions.MaxHeight; } // Applying MaxHeight and MaxWidth limitations if (maxHeight != null && (int)maxHeight < newHeight) { newHeight = (int)maxHeight; newWidth = (int)(width * (double)(int)maxHeight / height); } if (maxWidth != null && (int)maxWidth < newWidth) { newWidth = (int)maxWidth; newHeight = (int)(height * (double)(int)maxWidth / width); } return newWidth != width || newHeight != height; }
/// <summary> /// Gets resizing options from query string /// </summary> /// <param name="queryString">The query string.</param> /// <returns>Resizing options</returns> private static ResizingOptions FromQueryString(NameValueCollection queryString) { var result = new ResizingOptions(); string str = queryString["w"]; if (!string.IsNullOrEmpty(str)) { result.Width = int.Parse(str); } str = queryString["h"]; if (!string.IsNullOrEmpty(str)) { result.Height = int.Parse(str); } str = queryString["mw"]; if (!string.IsNullOrEmpty(str)) { result.MaxWidth = int.Parse(str); } str = queryString["mh"]; if (!string.IsNullOrEmpty(str)) { result.MaxHeight = int.Parse(str); } str = queryString["q"]; if (!string.IsNullOrEmpty(str)) { result.QualityOverride = int.Parse(str); if (result.QualityOverride < 1) result.QualityOverride = 1; if (result.QualityOverride > 100) result.QualityOverride = 100; } ResizingAction resizingAction; string action = queryString["action"]; if (!action.IsNullOrEmpty() && Enum.TryParse(action, true, out resizingAction)) { result.ResizingAction = resizingAction; } else { result.ResizingAction = Media.ResizingAction.Stretch; } return result; }
/// <summary> /// Gets the resized image. /// </summary> /// <param name="httpServerUtility">An instance of <see cref="System.Web.HttpServerUtility" />.</param> /// <param name="file">The media file.</param> /// <param name="resizingOptions">The resizing options.</param> /// <param name="targetImageFormat">The target image format.</param> /// <returns>A full file path to a resized image; null if there's no need to resize the image</returns> public static string GetResizedImage(HttpServerUtility httpServerUtility, IMediaFile file, ResizingOptions resizingOptions, ImageFormat targetImageFormat) { Verify.ArgumentNotNull(file, "file"); Verify.That(ImageFormatIsSupported(targetImageFormat), "Unsupported image format '{0}'", targetImageFormat); if (_resizedImagesDirectoryPath == null) { _resizedImagesDirectoryPath = httpServerUtility.MapPath(ResizedImagesCacheDirectory); if (!C1Directory.Exists(_resizedImagesDirectoryPath)) { C1Directory.CreateDirectory(_resizedImagesDirectoryPath); } } string imageKey = file.CompositePath; bool isNativeProvider = file is FileSystemFileBase; string imageSizeCacheKey = "ShowMedia.ashx image size " + imageKey; Size? imageSize = HttpRuntime.Cache.Get(imageSizeCacheKey) as Size?; Bitmap bitmap = null; Stream fileStream = null; try { if (imageSize == null) { fileStream = file.GetReadStream(); Size calculatedSize; if (!ImageSizeReader.TryGetSize(fileStream, out calculatedSize)) { fileStream.Dispose(); fileStream = file.GetReadStream(); bitmap = new Bitmap(fileStream); calculatedSize = new Size { Width = bitmap.Width, Height = bitmap.Height }; } imageSize = calculatedSize; // We can provider cache dependency only for the native media provider var cacheDependency = isNativeProvider ? new CacheDependency((file as FileSystemFileBase).SystemPath) : null; HttpRuntime.Cache.Add(imageSizeCacheKey, imageSize, cacheDependency, DateTime.MaxValue, CacheExpirationTimeSpan, CacheItemPriority.Normal, null); } int newWidth, newHeight; bool centerCrop; bool needToResize = CalculateSize(imageSize.Value.Width, imageSize.Value.Height, resizingOptions, out newWidth, out newHeight, out centerCrop); needToResize = needToResize || resizingOptions.CustomQuality; if (!needToResize) { return(null); } int filePathHash = imageKey.GetHashCode(); string centerCroppedString = centerCrop ? "c" : string.Empty; string fileExtension = _ImageFormat2Extension[targetImageFormat]; string resizedImageFileName = string.Format("{0}x{1}_{2}{3}_{4}.{5}", newWidth, newHeight, filePathHash, centerCroppedString, resizingOptions.Quality, fileExtension); string imageFullPath = Path.Combine(_resizedImagesDirectoryPath, resizedImageFileName); if (!C1File.Exists(imageFullPath) || C1File.GetLastWriteTime(imageFullPath) != file.LastWriteTime) { if (bitmap == null) { fileStream = file.GetReadStream(); bitmap = new Bitmap(fileStream); } ResizeImage(bitmap, imageFullPath, newWidth, newHeight, centerCrop, targetImageFormat, resizingOptions.Quality); if (file.LastWriteTime.HasValue) { C1File.SetLastWriteTime(imageFullPath, file.LastWriteTime.Value); } } return(imageFullPath); } finally { if (bitmap != null) { bitmap.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } }
private static bool CalculateSize(int width, int height, ResizingOptions resizingOptions, out int newWidth, out int newHeight, out bool centerCrop) { // Can be refactored to use System.Drawing.Size class instead of (width & height). if (width == 0 || height == 0) { newHeight = newWidth = 0; centerCrop = false; return(false); } Verify.ArgumentCondition(width > 0, "width", "Negative values aren't allowed"); Verify.ArgumentCondition(height > 0, "height", "Negative values aren't allowed"); centerCrop = false; // If both height and width are defined - we have "scalling" if (resizingOptions.Height != null && resizingOptions.Width != null) { newHeight = (int)resizingOptions.Height; newWidth = (int)resizingOptions.Width; // we do not allow scalling to a size, bigger than original one if (newHeight > height) { newHeight = height; } if (newWidth > width) { newWidth = width; } // If the target dimensions are bigger or the same size as of the image - no resizing is done if (newWidth == width && newHeight == height) { return(false); } switch (resizingOptions.ResizingAction) { case ResizingAction.Stretch: // no additional logic break; case ResizingAction.Crop: centerCrop = true; break; case ResizingAction.Fit: case ResizingAction.Fill: // No float point division for better precision Int64 heightProportionArea = (Int64)newHeight * width; Int64 widthProportionArea = (Int64)newWidth * height; if (heightProportionArea == widthProportionArea) { break; } if ((heightProportionArea > widthProportionArea) // (newHeight / height) > (newWidth / width) ^ (resizingOptions.ResizingAction == ResizingAction.Fit)) { newWidth = (int)(heightProportionArea / height); // newWidth = width * (newHeight / height) } else { newHeight = (int)(widthProportionArea / width); // newHeight = height * (newWidth / width) } break; } return(true); } newWidth = width; newHeight = height; // If image doesn't fit to bondaries "maxWidth X maxHeight", downsizing it int?maxWidth = resizingOptions.Width; if (resizingOptions.MaxWidth != null && (maxWidth == null || resizingOptions.MaxWidth < maxWidth)) { maxWidth = resizingOptions.MaxWidth; } int?maxHeight = resizingOptions.Height; if (resizingOptions.MaxHeight != null && (maxHeight == null || resizingOptions.MaxHeight < maxHeight)) { maxHeight = resizingOptions.MaxHeight; } // Applying MaxHeight and MaxWidth limitations if (maxHeight != null && (int)maxHeight < newHeight) { newHeight = (int)maxHeight; newWidth = (int)(width * (double)(int)maxHeight / height); } if (maxWidth != null && (int)maxWidth < newWidth) { newWidth = (int)maxWidth; newHeight = (int)(height * (double)(int)maxWidth / width); } return(newWidth != width || newHeight != height); }