Obsoletes UmbracoFile with new UmbracoMediaFile in the Core assembly and wraps the legacy class to use the new one. Improves performance of UmbracoMediaFile by ensuring any IO is lazy loaded and then saved to a local property so it doesn't need to re-read the file for things like length/size.

Conflicts:
	src/Umbraco.Core/Umbraco.Core.csproj
This commit is contained in:
Shannon
2013-07-23 17:59:44 +10:00
parent 2e91c89c02
commit d1eb8fd9eb
7 changed files with 321 additions and 166 deletions

View File

@@ -5,6 +5,7 @@ using System.Text;
namespace umbraco.cms.businesslogic.Files
{
[Obsolete("This is no longer used ane will be removed from the codebase in the future")]
public interface IFile
{
string Filename { get; }

View File

@@ -5,6 +5,7 @@ using System.Text;
namespace umbraco.cms.businesslogic.Files
{
[Obsolete("This is no longer used ane will be removed from the codebase in the future")]
public class NotAnImageException : Exception
{
public NotAnImageException()

View File

@@ -10,24 +10,26 @@ using Umbraco.Core.IO;
namespace umbraco.cms.businesslogic.Files
{
[Obsolete("Use Umbraco.Core.IO.UmbracoMediaFile instead")]
public class UmbracoFile : IFile
{
private readonly MediaFileSystem _fs;
private readonly UmbracoMediaFile _mediaFile;
#region Constructors
public UmbracoFile()
{
_fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
_mediaFile = new UmbracoMediaFile();
}
public UmbracoFile(string path)
{
_fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
_mediaFile = new UmbracoMediaFile(path);
}
Path = path;
Initialize();
internal UmbracoFile(UmbracoMediaFile mediaFile)
{
_mediaFile = mediaFile;
}
#endregion
@@ -38,57 +40,46 @@ namespace umbraco.cms.businesslogic.Files
public static UmbracoFile Save(HttpPostedFile file, string path)
{
return Save(file.InputStream, path);
return new UmbracoFile(UmbracoMediaFile.Save(file.InputStream, path));
}
public static UmbracoFile Save(HttpPostedFileBase file, string path)
{
return Save(file.InputStream, path);
return new UmbracoFile(UmbracoMediaFile.Save(file.InputStream, path));
}
public static UmbracoFile Save(Stream inputStream, string path)
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
fs.AddFile(path, inputStream);
return new UmbracoFile(path);
return new UmbracoFile(UmbracoMediaFile.Save(inputStream, path));
}
public static UmbracoFile Save(byte[] file, string relativePath)
{
return Save(new MemoryStream(file), relativePath);
return new UmbracoFile(UmbracoMediaFile.Save(new MemoryStream(file), relativePath));
}
public static UmbracoFile Save(HttpPostedFile file)
{
var tempDir = System.IO.Path.Combine("uploads", Guid.NewGuid().ToString());
return Save(file, tempDir);
return new UmbracoFile(UmbracoMediaFile.Save(file));
}
//filebase overload...
public static UmbracoFile Save(HttpPostedFileBase file)
{
var tempDir = System.IO.Path.Combine("uploads", Guid.NewGuid().ToString());
return Save(file, tempDir);
return new UmbracoFile(UmbracoMediaFile.Save(file));
}
#endregion
private void Initialize()
public string Filename
{
Filename = _fs.GetFileName(Path);
Length = _fs.GetSize(Path);
Extension = _fs.GetExtension(Path) != null
? _fs.GetExtension(Path).Substring(1).ToLowerInvariant()
: "";
Url = _fs.GetUrl(Path);
get { return _mediaFile.Filename; }
}
#region IFile Members
public string Filename { get; private set; }
public string Extension { get; private set; }
public string Extension
{
get { return _mediaFile.Extension; }
}
[Obsolete("LocalName is obsolete, please use Url instead", false)]
public string LocalName
@@ -96,160 +87,47 @@ namespace umbraco.cms.businesslogic.Files
get { return Url; }
}
public string Path { get; private set; }
public string Path
{
get { return _mediaFile.Path; }
}
public string Url { get; private set; }
public string Url
{
get { return _mediaFile.Url; }
}
public long Length { get; private set; }
public long Length
{
get { return _mediaFile.Length; }
}
public bool SupportsResizing
{
get
{
return ("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", Extension));
}
get { return _mediaFile.SupportsResizing; }
}
public string GetFriendlyName()
{
return Filename.SplitPascalCasing().ToFirstUpperInvariant();
return _mediaFile.GetFriendlyName();
}
public System.Tuple<int, int> GetDimensions()
{
EnsureFileSupportsResizing();
var fs = _fs.OpenFile(Path);
var image = Image.FromStream(fs);
var fileWidth = image.Width;
var fileHeight = image.Height;
fs.Close();
image.Dispose();
return new System.Tuple<int, int>(fileWidth, fileHeight);
var size = _mediaFile.GetDimensions();
return new System.Tuple<int, int>(size.Width, size.Height);
}
public string Resize(int width, int height)
{
EnsureFileSupportsResizing();
var fileNameThumb = DoResize(width, height, 0, string.Empty);
return _fs.GetUrl(fileNameThumb);
return _mediaFile.Resize(width, height);
}
public string Resize(int maxWidthHeight, string fileNameAddition)
{
EnsureFileSupportsResizing();
var fileNameThumb = DoResize(GetDimensions().Item1, GetDimensions().Item2, maxWidthHeight, fileNameAddition);
return _fs.GetUrl(fileNameThumb);
return _mediaFile.Resize(maxWidthHeight, fileNameAddition);
}
private string DoResize(int width, int height, int maxWidthHeight, string fileNameAddition)
{
using (var fs = _fs.OpenFile(Path))
{
using (var image = Image.FromStream(fs))
{
var fileNameThumb = string.IsNullOrWhiteSpace(fileNameAddition)
? string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)))
: string.Format("{0}_{1}.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)), fileNameAddition);
var thumbnail = GenerateThumbnail(image, maxWidthHeight, width, height, fileNameThumb, maxWidthHeight == 0);
return thumbnail.FileName;
}
}
}
#endregion
private void EnsureFileSupportsResizing()
{
if (SupportsResizing == false)
throw new NotAnImageException(string.Format("The file {0} is not an image, so can't get dimensions", Filename));
}
private ResizedImage GenerateThumbnail(Image image, int maxWidthHeight, int fileWidth, int fileHeight, string thumbnailFileName, bool useFixedDimensions)
{
// Generate thumbnail
float f = 1;
if (useFixedDimensions == false)
{
var fx = (float)image.Size.Width / (float)maxWidthHeight;
var fy = (float)image.Size.Height / (float)maxWidthHeight;
// must fit in thumbnail size
f = Math.Max(fx, fy);
}
var widthTh = (int)Math.Round((float)fileWidth / f);
var heightTh = (int)Math.Round((float)fileHeight / f);
// fixes for empty width or height
if (widthTh == 0)
widthTh = 1;
if (heightTh == 0)
heightTh = 1;
// Create new image with best quality settings
using (var bp = new Bitmap(widthTh, heightTh))
{
using (var g = Graphics.FromImage(bp))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
// Copy the old image to the new and resized
var rect = new Rectangle(0, 0, widthTh, heightTh);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy metadata
var imageEncoders = ImageCodecInfo.GetImageEncoders();
var codec = Extension.ToLower() == "png" || Extension.ToLower() == "gif"
? imageEncoders.Single(t => t.MimeType.Equals("image/png"))
: imageEncoders.Single(t => t.MimeType.Equals("image/jpeg"));
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image using the dimensions of the image
var newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", string.Format("{0}x{1}", widthTh, heightTh));
using (var ms = new MemoryStream())
{
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
_fs.AddFile(newFileName, ms);
}
return new ResizedImage(widthTh, heightTh, newFileName);
}
}
}
}
internal class ResizedImage
{
public ResizedImage()
{
}
public ResizedImage(int width, int height, string fileName)
{
Width = width;
Height = height;
FileName = fileName;
}
public int Width { get; set; }
public int Height { get; set; }
public string FileName { get; set; }
}
}

View File

@@ -169,12 +169,12 @@ namespace umbraco.cms.businesslogic.datatype
object propertyValue)
{
XmlNode propertyNode = uploadFieldConfigNode.SelectSingleNode(propertyAlias);
if (propertyNode != null && !String.IsNullOrEmpty(propertyNode.FirstChild.Value))
if (propertyNode != null && !string.IsNullOrEmpty(propertyNode.FirstChild.Value))
{
if (content.getProperty(propertyNode.FirstChild.Value) != null)
var prop = content.getProperty(propertyNode.FirstChild.Value);
if (prop != null)
{
content.getProperty(propertyNode.FirstChild.Value)
.Value = propertyValue;
prop.Value = propertyValue;
}
}
}