diff options
| author | Eric Reed <ebr@mediabrowser3.com> | 2013-11-07 12:27:21 -0500 |
|---|---|---|
| committer | Eric Reed <ebr@mediabrowser3.com> | 2013-11-07 12:27:21 -0500 |
| commit | bda3a301e70b8cdca8af06e6395701ec98a89e09 (patch) | |
| tree | c32ec5d48a48a64bb9e06dd827da9fbc04ce6406 /MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs | |
| parent | 63554bde5be929588e9073415ea811170264508b (diff) | |
| parent | 01f1ed05b9a401939ccbd586e07951c144232608 (diff) | |
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
Diffstat (limited to 'MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs | 131 |
1 files changed, 82 insertions, 49 deletions
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index a439251db..78dcf6fd0 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -3,11 +3,11 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// Class ImageProcessor /// </summary> - public class ImageProcessor : IImageProcessor + public class ImageProcessor : IImageProcessor, IDisposable { /// <summary> /// The us culture @@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// The _cached imaged sizes /// </summary> - private readonly ConcurrentDictionary<string, ImageSize> _cachedImagedSizes = new ConcurrentDictionary<string, ImageSize>(); + private readonly ConcurrentDictionary<Guid, ImageSize> _cachedImagedSizes; /// <summary> /// Gets the list of currently registered image processors @@ -50,21 +50,41 @@ namespace MediaBrowser.Server.Implementations.Drawing private readonly ILogger _logger; private readonly IFileSystem _fileSystem; + private readonly IJsonSerializer _jsonSerializer; + private readonly IServerApplicationPaths _appPaths; private readonly string _imageSizeCachePath; private readonly string _croppedWhitespaceImageCachePath; private readonly string _enhancedImageCachePath; private readonly string _resizedImageCachePath; - public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem) + public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer) { _logger = logger; _fileSystem = fileSystem; + _jsonSerializer = jsonSerializer; + _appPaths = appPaths; _imageSizeCachePath = Path.Combine(appPaths.ImageCachePath, "image-sizes"); _croppedWhitespaceImageCachePath = Path.Combine(appPaths.ImageCachePath, "cropped-images"); _enhancedImageCachePath = Path.Combine(appPaths.ImageCachePath, "enhanced-images"); _resizedImageCachePath = Path.Combine(appPaths.ImageCachePath, "resized-images"); + + _saveImageSizeTimer = new Timer(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite); + + Dictionary<Guid, ImageSize> sizeDictionary; + + try + { + sizeDictionary = jsonSerializer.DeserializeFromFile<Dictionary<Guid, ImageSize>>(ImageSizeFile); + } + catch (IOException) + { + // No biggie + sizeDictionary = new Dictionary<Guid, ImageSize>(); + } + + _cachedImagedSizes = new ConcurrentDictionary<Guid, ImageSize>(sizeDictionary); } public void AddParts(IEnumerable<IImageEnhancer> enhancers) @@ -85,6 +105,17 @@ namespace MediaBrowser.Server.Implementations.Drawing } var originalImagePath = options.OriginalImagePath; + + if (options.HasDefaultOptions()) + { + // Just spit out the original file if all the options are default + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) + { + await fileStream.CopyToAsync(toStream).ConfigureAwait(false); + return; + } + } + var dateModified = options.OriginalImageDateModified; if (options.CropWhiteSpace) @@ -106,6 +137,16 @@ namespace MediaBrowser.Server.Implementations.Drawing // Determine the output size based on incoming parameters var newSize = DrawingUtils.Resize(originalImageSize, options.Width, options.Height, options.MaxWidth, options.MaxHeight); + if (options.HasDefaultOptionsWithoutSize() && newSize.Equals(originalImageSize)) + { + // Just spit out the original file the new size equals the old + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) + { + await fileStream.CopyToAsync(toStream).ConfigureAwait(false); + return; + } + } + var quality = options.Quality ?? 90; var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, options.OutputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.BackgroundColor); @@ -465,11 +506,13 @@ namespace MediaBrowser.Server.Implementations.Drawing ImageSize size; - if (!_cachedImagedSizes.TryGetValue(name, out size)) + var cacheHash = name.GetMD5(); + + if (!_cachedImagedSizes.TryGetValue(cacheHash, out size)) { - size = GetImageSizeInternal(name, path); + size = GetImageSizeInternal(path); - _cachedImagedSizes.AddOrUpdate(name, size, (keyName, oldValue) => size); + _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size); } return size; @@ -478,62 +521,47 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// Gets the image size internal. /// </summary> - /// <param name="cacheKey">The cache key.</param> /// <param name="path">The path.</param> /// <returns>ImageSize.</returns> - private ImageSize GetImageSizeInternal(string cacheKey, string path) + private ImageSize GetImageSizeInternal(string path) { - // Now check the file system cache - var fullCachePath = GetCachePath(_imageSizeCachePath, cacheKey, ".txt"); + var size = ImageHeader.GetDimensions(path, _logger, _fileSystem); - try - { - var result = File.ReadAllText(fullCachePath).Split('|'); + StartSaveImageSizeTimer(); - return new ImageSize - { - Width = double.Parse(result[0], UsCulture), - Height = double.Parse(result[1], UsCulture) - }; - } - catch (IOException) - { - // Cache file doesn't exist or is currently being written to - } + return new ImageSize { Width = size.Width, Height = size.Height }; + } - var syncLock = GetObjectLock(fullCachePath); + private readonly Timer _saveImageSizeTimer; + private const int SaveImageSizeTimeout = 5000; + private readonly object _saveImageSizeLock = new object(); + private void StartSaveImageSizeTimer() + { + _saveImageSizeTimer.Change(SaveImageSizeTimeout, Timeout.Infinite); + } - lock (syncLock) + private void SaveImageSizeCallback(object state) + { + lock (_saveImageSizeLock) { try { - var result = File.ReadAllText(fullCachePath).Split('|'); - - return new ImageSize - { - Width = double.Parse(result[0], UsCulture), - Height = double.Parse(result[1], UsCulture) - }; - } - catch (FileNotFoundException) - { - // Cache file doesn't exist no biggie + var path = ImageSizeFile; + Directory.CreateDirectory(Path.GetDirectoryName(path)); + _jsonSerializer.SerializeToFile(_cachedImagedSizes, path); } - catch (DirectoryNotFoundException) + catch (Exception ex) { - // Cache file doesn't exist no biggie + _logger.ErrorException("Error saving image size file", ex); } + } + } - var size = ImageHeader.GetDimensions(path, _logger, _fileSystem); - - var parentPath = Path.GetDirectoryName(fullCachePath); - - Directory.CreateDirectory(parentPath); - - // Update the file system cache - File.WriteAllText(fullCachePath, size.Width.ToString(UsCulture) + @"|" + size.Height.ToString(UsCulture)); - - return new ImageSize { Width = size.Width, Height = size.Height }; + private string ImageSizeFile + { + get + { + return Path.Combine(_appPaths.DataPath, "imagesizes.json"); } } @@ -862,5 +890,10 @@ namespace MediaBrowser.Server.Implementations.Drawing }).ToList(); } + + public void Dispose() + { + _saveImageSizeTimer.Dispose(); + } } } |
