diff --git a/src/Umbraco.Core/IO/FileSystemExtensions.cs b/src/Umbraco.Core/IO/FileSystemExtensions.cs index 24dc815560..78f39466f8 100644 --- a/src/Umbraco.Core/IO/FileSystemExtensions.cs +++ b/src/Umbraco.Core/IO/FileSystemExtensions.cs @@ -2,12 +2,10 @@ using Umbraco.Core.CodeAnnotations; namespace Umbraco.Core.IO -{ - [UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")] +{ public static class FileSystemExtensions { - [UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")] - internal static long GetSize(this IFileSystem fs, string path) + public static long GetSize(this IFileSystem fs, string path) { using (var s = fs.OpenFile(path)) { @@ -18,20 +16,17 @@ namespace Umbraco.Core.IO } } - [UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")] - internal static void CopyFile(this IFileSystem fs, string path, string newPath) + public static void CopyFile(this IFileSystem fs, string path, string newPath) { fs.AddFile(newPath, fs.OpenFile(path)); } - [UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")] - internal static string GetExtension(this IFileSystem fs, string path) + public static string GetExtension(this IFileSystem fs, string path) { return Path.GetExtension(fs.GetFullPath(path)); } - [UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")] - internal static string GetFileName(this IFileSystem fs, string path) + public static string GetFileName(this IFileSystem fs, string path) { return Path.GetFileName(fs.GetFullPath(path)); } diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 4baa61fb92..04a7ccb27b 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -363,8 +363,7 @@ namespace Umbraco.Core.Models /// Alias of the property to save the value on /// Name of the file /// to save to disk - public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName, - Stream fileStream) + public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName, Stream fileStream) { var name = IOHelper.SafeFileName(fileName); @@ -378,75 +377,82 @@ namespace Umbraco.Core.Models if (property == null) return; - bool supportsResizing = false; var numberedFolder = MediaSubfolderCounter.Current.Increment(); - string fileName = UmbracoSettings.UploadAllowDirectories + var fileName = UmbracoSettings.UploadAllowDirectories ? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name) : numberedFolder + "-" + name; - string extension = Path.GetExtension(name).Substring(1).ToLowerInvariant(); + var extension = Path.GetExtension(name).Substring(1).ToLowerInvariant(); + + //the file size is the length of the stream in bytes + var fileSize = fileStream.Length; var fs = FileSystemProviderManager.Current.GetFileSystemProvider(); fs.AddFile(fileName, fileStream); - + //Check if file supports resizing and create thumbnails - if (("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", extension))) - { - supportsResizing = true; + var supportsResizing = ("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", extension)); - // Make default thumbnail - var thumbUrl = Resize(fs, fileName, extension, 100, "thumb"); - - //Look up Prevalues for this upload datatype - if it is an upload datatype - var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField); - if (property.PropertyType.DataTypeId == uploadFieldId) - { - //Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId - var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId); - var thumbnailSizes = values.FirstOrDefault(); - //Additional thumbnails configured as prevalues on the DataType - if (thumbnailSizes != null) - { - char sep = (!thumbnailSizes.Contains("") && thumbnailSizes.Contains(",")) ? ',' : ';'; - - foreach (string thumb in thumbnailSizes.Split(sep)) - { - int thumbSize; - if (thumb != "" && int.TryParse(thumb, out thumbSize)) - { - Resize(fs, fileName, extension, thumbSize, string.Format("thumb_{0}", thumbSize)); - } - } - } - } - } + //the config section used to auto-fill properties + XmlNode uploadFieldConfigNode = null; //Check for auto fill of additional properties if (UmbracoSettings.ImageAutoFillImageProperties != null) { - XmlNode uploadFieldConfigNode = + uploadFieldConfigNode = UmbracoSettings.ImageAutoFillImageProperties.SelectSingleNode( string.Format("uploadField [@alias = \"{0}\"]", propertyTypeAlias)); + } - if (uploadFieldConfigNode != null) - { - //Only add dimensions to web images - if (supportsResizing) + if (supportsResizing) + { + //get the original image from the original stream + if (fileStream.CanSeek) fileStream.Seek(0, 0); + using (var originalImage = Image.FromStream(fileStream)) + { + // Make default thumbnail + Resize(fs, fileName, extension, 100, "thumb", originalImage); + + //Look up Prevalues for this upload datatype - if it is an upload datatype + var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField); + if (property.PropertyType.DataTypeId == uploadFieldId) { - SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", GetDimensions(fs, fileName).Item1.ToString(CultureInfo.InvariantCulture)); - SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", GetDimensions(fs, fileName).Item2.ToString(CultureInfo.InvariantCulture)); - } - else - { - SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", string.Empty); - SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", string.Empty); + //Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId + var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId); + var thumbnailSizes = values.FirstOrDefault(); + //Additional thumbnails configured as prevalues on the DataType + if (thumbnailSizes != null) + { + char sep = (!thumbnailSizes.Contains("") && thumbnailSizes.Contains(",")) ? ',' : ';'; + + foreach (var thumb in thumbnailSizes.Split(sep)) + { + int thumbSize; + if (thumb != "" && int.TryParse(thumb, out thumbSize)) + { + Resize(fs, fileName, extension, thumbSize, string.Format("thumb_{0}", thumbSize), originalImage); + } + } + } } - SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fs.GetSize(fileName).ToString(CultureInfo.InvariantCulture)); - SetPropertyValue(content, uploadFieldConfigNode, "extensionFieldAlias", extension); + //while the image is still open, we'll check if we need to auto-populate the image properties + if (uploadFieldConfigNode != null) + { + SetPropertyValue(content, uploadFieldConfigNode, "widthFieldAlias", originalImage.Width.ToString(CultureInfo.InvariantCulture)); + SetPropertyValue(content, uploadFieldConfigNode, "heightFieldAlias", originalImage.Height.ToString(CultureInfo.InvariantCulture)); + } + } } + //if auto-fill is true, then fill the remaining, non-image properties + if (uploadFieldConfigNode != null) + { + SetPropertyValue(content, uploadFieldConfigNode, "lengthFieldAlias", fileSize.ToString(CultureInfo.InvariantCulture)); + SetPropertyValue(content, uploadFieldConfigNode, "extensionFieldAlias", extension); + } + //Set the value of the property to that of the uploaded file's url property.Value = fs.GetUrl(fileName); } @@ -460,71 +466,37 @@ namespace Umbraco.Core.Models } } - private static string Resize(MediaFileSystem fileSystem, string path, string extension, int maxWidthHeight, string fileNameAddition) + private static ResizedImage Resize(MediaFileSystem fileSystem, string path, string extension, int maxWidthHeight, string fileNameAddition, Image originalImage) { - var fileNameThumb = DoResize(fileSystem, path, extension, GetDimensions(fileSystem, path).Item1, GetDimensions(fileSystem, path).Item2, maxWidthHeight, fileNameAddition); - - return fileSystem.GetUrl(fileNameThumb); - } - - private static Tuple GetDimensions(IFileSystem fileSystem, string path) - { - using (var fs = fileSystem.OpenFile(path)) - { - using (var image = Image.FromStream(fs)) - { - var fileWidth = image.Width; - var fileHeight = image.Height; - return new Tuple(fileWidth, fileHeight); - } - } - } - - private static string DoResize(MediaFileSystem fileSystem, string path, string extension, int width, int height, int maxWidthHeight, string fileNameAddition) - { - using (var fs = fileSystem.OpenFile(path)) - { - using (var image = Image.FromStream(fs)) - { - fs.Close(); - - var fileNameThumb = String.IsNullOrEmpty(fileNameAddition) + var fileNameThumb = String.IsNullOrEmpty(fileNameAddition) ? string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", path.Substring(0, path.LastIndexOf("."))) : string.Format("{0}_{1}.jpg", path.Substring(0, path.LastIndexOf(".")), fileNameAddition); - var thumb = GenerateThumbnail(fileSystem, - image, - maxWidthHeight, - width, - height, - path, - extension, - fileNameThumb, - maxWidthHeight == 0); + var thumb = GenerateThumbnail(fileSystem, + originalImage, + maxWidthHeight, + extension, + fileNameThumb, + maxWidthHeight == 0); - fileNameThumb = thumb.Item3; - - return fileNameThumb; - } - } + return thumb; } - - private static Tuple GenerateThumbnail(MediaFileSystem fileSystem, Image image, int maxWidthHeight, int fileWidth, - int fileHeight, string fullFilePath, string extension, - string thumbnailFileName, bool useFixedDimensions) + + private static ResizedImage GenerateThumbnail(MediaFileSystem fileSystem, Image image, int maxWidthHeight, string extension, string thumbnailFileName, bool useFixedDimensions) { // Generate thumbnail float f = 1; if (!useFixedDimensions) { - var fx = (float)image.Size.Width / (float)maxWidthHeight; - var fy = (float)image.Size.Height / (float)maxWidthHeight; + var fx = image.Width / (float)maxWidthHeight; + var fy = image.Height / (float)maxWidthHeight; // must fit in thumbnail size f = Math.Max(fx, fy); //if (f < 1) f = 1; } - var widthTh = (int)Math.Round((float)fileWidth / f); int heightTh = (int)Math.Round((float)fileHeight / f); + var widthTh = (int)Math.Round(image.Width / f); + var heightTh = (int)Math.Round(image.Height / f); // fixes for empty width or height if (widthTh == 0) @@ -548,7 +520,7 @@ namespace Umbraco.Core.Models // Copy metadata var imageEncoders = ImageCodecInfo.GetImageEncoders(); - ImageCodecInfo codec = null; + ImageCodecInfo codec; if (extension.ToLower() == "png" || extension.ToLower() == "gif") codec = imageEncoders.Single(t => t.MimeType.Equals("image/png")); else @@ -569,7 +541,7 @@ namespace Umbraco.Core.Models fileSystem.AddFile(newFileName, ms); } - return new Tuple(widthTh, heightTh, newFileName); + return new ResizedImage(widthTh, heightTh, newFileName); } } }