diff options
Diffstat (limited to 'Emby.Drawing/ImageProcessor.cs')
| -rw-r--r-- | Emby.Drawing/ImageProcessor.cs | 144 |
1 files changed, 115 insertions, 29 deletions
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 88ead3a5f..1d3f4a8e3 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -17,12 +17,11 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; using Emby.Drawing.Common; - -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; -using TagLib; +using MediaBrowser.Model.Extensions; namespace Emby.Drawing { @@ -46,7 +45,7 @@ namespace Emby.Drawing /// Image processors are specialized metadata providers that run after the normal ones /// </summary> /// <value>The image enhancers.</value> - public IEnumerable<IImageEnhancer> ImageEnhancers { get; private set; } + public IImageEnhancer[] ImageEnhancers { get; private set; } /// <summary> /// The _logger @@ -58,22 +57,24 @@ namespace Emby.Drawing private readonly IServerApplicationPaths _appPaths; private IImageEncoder _imageEncoder; private readonly Func<ILibraryManager> _libraryManager; + private readonly Func<IMediaEncoder> _mediaEncoder; public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IImageEncoder imageEncoder, - Func<ILibraryManager> libraryManager, ITimerFactory timerFactory) + Func<ILibraryManager> libraryManager, ITimerFactory timerFactory, Func<IMediaEncoder> mediaEncoder) { _logger = logger; _fileSystem = fileSystem; _jsonSerializer = jsonSerializer; _imageEncoder = imageEncoder; _libraryManager = libraryManager; + _mediaEncoder = mediaEncoder; _appPaths = appPaths; - ImageEnhancers = new List<IImageEnhancer>(); + ImageEnhancers = new IImageEnhancer[] { }; _saveImageSizeTimer = timerFactory.Create(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite); ImageHelper.ImageProcessor = this; @@ -122,7 +123,37 @@ namespace Emby.Drawing { get { - return _imageEncoder.SupportedInputFormats; + return new string[] + { + "tiff", + "tif", + "jpeg", + "jpg", + "png", + "aiff", + "cr2", + "crw", + "dng", + + // Remove until supported + //"nef", + "orf", + "pef", + "arw", + "webp", + "gif", + "bmp", + "erf", + "raf", + "rw2", + "nrw", + "dng", + "ico", + "astc", + "ktx", + "pkm", + "wbmp" + }; } } @@ -186,7 +217,7 @@ namespace Emby.Drawing } var originalImage = options.Image; - IHasImages item = options.Item; + IHasMetadata item = options.Item; if (!originalImage.IsLocalFile) { @@ -205,6 +236,10 @@ namespace Emby.Drawing return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); } + var supportedImageInfo = await GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false); + originalImagePath = supportedImageInfo.Item1; + dateModified = supportedImageInfo.Item2; + if (options.Enhancers.Count > 0) { if (item == null) @@ -262,11 +297,6 @@ namespace Emby.Drawing var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath)); - if (item == null && string.Equals(options.ItemType, typeof(Photo).Name, StringComparison.OrdinalIgnoreCase)) - { - item = _libraryManager().GetItemById(options.ItemId); - } - if (options.CropWhiteSpace && !SupportsTransparency(originalImagePath)) { options.CropWhiteSpace = false; @@ -287,6 +317,15 @@ namespace Emby.Drawing return new Tuple<string, string, DateTime>(cacheFilePath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(cacheFilePath)); } + catch (ArgumentOutOfRangeException ex) + { + // Decoder failed to decode it +#if DEBUG + _logger.ErrorException("Error encoding image", ex); +#endif + // Just spit out the original file if all the options are default + return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); + } catch (Exception ex) { // If it fails for whatever reason, return the original image @@ -606,7 +645,7 @@ namespace Emby.Drawing /// <param name="image">The image.</param> /// <returns>Guid.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public string GetImageCacheTag(IHasImages item, ItemImageInfo image) + public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image) { if (item == null) { @@ -620,7 +659,7 @@ namespace Emby.Drawing var supportedEnhancers = GetSupportedEnhancers(item, image.Type); - return GetImageCacheTag(item, image, supportedEnhancers.ToList()); + return GetImageCacheTag(item, image, supportedEnhancers); } /// <summary> @@ -631,7 +670,7 @@ namespace Emby.Drawing /// <param name="imageEnhancers">The image enhancers.</param> /// <returns>Guid.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public string GetImageCacheTag(IHasImages item, ItemImageInfo image, List<IImageEnhancer> imageEnhancers) + public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image, List<IImageEnhancer> imageEnhancers) { if (item == null) { @@ -662,7 +701,43 @@ namespace Emby.Drawing var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList(); cacheKeys.Add(originalImagePath + dateModified.Ticks); - return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N"); + return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N"); + } + + private async Task<Tuple<string, DateTime>> GetSupportedImage(string originalImagePath, DateTime dateModified) + { + var inputFormat = (Path.GetExtension(originalImagePath) ?? string.Empty) + .TrimStart('.') + .Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase); + + if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat, StringComparer.OrdinalIgnoreCase)) + { + try + { + var filename = (originalImagePath + dateModified.Ticks.ToString(UsCulture)).GetMD5().ToString("N"); + + var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + ".webp"); + + var file = _fileSystem.GetFileInfo(outputPath); + if (!file.Exists) + { + await _mediaEncoder().ConvertImage(originalImagePath, outputPath).ConfigureAwait(false); + dateModified = _fileSystem.GetLastWriteTimeUtc(outputPath); + } + else + { + dateModified = file.LastWriteTimeUtc; + } + + originalImagePath = outputPath; + } + catch (Exception ex) + { + _logger.ErrorException("Image conversion failed for {0}", ex, originalImagePath); + } + } + + return new Tuple<string, DateTime>(originalImagePath, dateModified); } /// <summary> @@ -672,9 +747,9 @@ namespace Emby.Drawing /// <param name="imageType">Type of the image.</param> /// <param name="imageIndex">Index of the image.</param> /// <returns>Task{System.String}.</returns> - public async Task<string> GetEnhancedImage(IHasImages item, ImageType imageType, int imageIndex) + public async Task<string> GetEnhancedImage(IHasMetadata item, ImageType imageType, int imageIndex) { - var enhancers = GetSupportedEnhancers(item, imageType).ToList(); + var enhancers = GetSupportedEnhancers(item, imageType); var imageInfo = item.GetImageInfo(imageType, imageIndex); @@ -684,7 +759,7 @@ namespace Emby.Drawing } private async Task<Tuple<string, DateTime>> GetEnhancedImage(ItemImageInfo image, - IHasImages item, + IHasMetadata item, int imageIndex, List<IImageEnhancer> enhancers) { @@ -729,7 +804,7 @@ namespace Emby.Drawing /// item /// </exception> private async Task<string> GetEnhancedImageInternal(string originalImagePath, - IHasImages item, + IHasMetadata item, ImageType imageType, int imageIndex, IEnumerable<IImageEnhancer> supportedEnhancers, @@ -783,7 +858,7 @@ namespace Emby.Drawing /// <param name="imageType">Type of the image.</param> /// <param name="imageIndex">Index of the image.</param> /// <returns>Task{EnhancedImage}.</returns> - private async Task ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, string inputPath, string outputPath, IHasImages item, ImageType imageType, int imageIndex) + private async Task ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, string inputPath, string outputPath, IHasMetadata item, ImageType imageType, int imageIndex) { // Run the enhancers sequentially in order of priority foreach (var enhancer in imageEnhancers) @@ -868,29 +943,40 @@ namespace Emby.Drawing _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath); } - public IEnumerable<IImageEnhancer> GetSupportedEnhancers(IHasImages item, ImageType imageType) + public List<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType) { - return ImageEnhancers.Where(i => + var list = new List<IImageEnhancer>(); + + foreach (var i in ImageEnhancers) { try { - return i.Supports(item, imageType); + if (i.Supports(item, imageType)) + { + list.Add(i); + } } catch (Exception ex) { _logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name); - - return false; } - }); + } + return list; } private bool _disposed; public void Dispose() { _disposed = true; - _imageEncoder.Dispose(); + + var disposable = _imageEncoder as IDisposable; + if (disposable != null) + { + disposable.Dispose(); + } + _saveImageSizeTimer.Dispose(); + GC.SuppressFinalize(this); } private void CheckDisposed() |
