diff options
| author | Luke <luke.pulverenti@gmail.com> | 2017-09-20 13:22:39 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-20 13:22:39 -0400 |
| commit | eb2a1330045d802bfe0366df7105c220a36f111f (patch) | |
| tree | 2c1638c424ee9c0837c5de6d6e08a2398da69cdb /Emby.Drawing/ImageProcessor.cs | |
| parent | ec426d5c92875639ceac64477ce10fab3e639335 (diff) | |
| parent | a015e1208885bc6a8788db683c4fe47e93dc26b7 (diff) | |
Merge pull request #2897 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Drawing/ImageProcessor.cs')
| -rw-r--r-- | Emby.Drawing/ImageProcessor.cs | 129 |
1 files changed, 91 insertions, 38 deletions
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 8f3042e2a..f5a05db05 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -126,6 +126,7 @@ namespace Emby.Drawing return new string[] { "tiff", + "tif", "jpeg", "jpg", "png", @@ -202,10 +203,9 @@ namespace Emby.Drawing } private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp" }; - private bool SupportsTransparency(string path) + public bool SupportsTransparency(string path) { return TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); - ; } public async Task<Tuple<string, string, DateTime>> ProcessImage(ImageProcessingOptions options) @@ -238,6 +238,7 @@ namespace Emby.Drawing var supportedImageInfo = await GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false); originalImagePath = supportedImageInfo.Item1; dateModified = supportedImageInfo.Item2; + var requiresTransparency = TransparentImageTypes.Contains(Path.GetExtension(originalImagePath) ?? string.Empty); if (options.Enhancers.Count > 0) { @@ -252,10 +253,11 @@ namespace Emby.Drawing Type = originalImage.Type, Path = originalImagePath - }, item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); + }, requiresTransparency, item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); originalImagePath = tuple.Item1; dateModified = tuple.Item2; + requiresTransparency = tuple.Item3; } var photo = item as Photo; @@ -267,7 +269,7 @@ namespace Emby.Drawing orientation = photo.Orientation; } - if (options.HasDefaultOptions(originalImagePath) && !autoOrient) + if (options.HasDefaultOptions(originalImagePath) && (!autoOrient || !options.RequiresAutoOrientation)) { // Just spit out the original file if all the options are default return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); @@ -284,7 +286,7 @@ namespace Emby.Drawing var newSize = ImageHelper.GetNewImageSize(options, originalImageSize); var quality = options.Quality; - var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]); + var outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency); var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.Blur, options.BackgroundColor, options.ForegroundLayer); try @@ -296,11 +298,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; @@ -321,6 +318,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 @@ -331,6 +337,34 @@ namespace Emby.Drawing } } + private ImageFormat GetOutputFormat(ImageFormat[] clientSupportedFormats, bool requiresTransparency) + { + var serverFormats = GetSupportedImageOutputFormats(); + + // Client doesn't care about format, so start with webp if supported + if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp)) + { + return ImageFormat.Webp; + } + + // If transparency is needed and webp isn't supported, than png is the only option + if (requiresTransparency) + { + return ImageFormat.Png; + } + + foreach (var format in clientSupportedFormats) + { + if (serverFormats.Contains(format)) + { + return format; + } + } + + // We should never actually get here + return ImageFormat.Jpg; + } + private void CopyFile(string src, string destination) { try @@ -384,21 +418,6 @@ namespace Emby.Drawing return MimeTypes.GetMimeType(path); } - private ImageFormat GetOutputFormat(ImageFormat requestedFormat) - { - if (requestedFormat == ImageFormat.Webp && !_imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp)) - { - return ImageFormat.Png; - } - - return requestedFormat; - } - - private Tuple<string, DateTime> GetResult(string path) - { - return new Tuple<string, DateTime>(path, _fileSystem.GetLastWriteTimeUtc(path)); - } - /// <summary> /// Increment this when there's a change requiring caches to be invalidated /// </summary> @@ -705,13 +724,20 @@ namespace Emby.Drawing .TrimStart('.') .Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase); + // These are just jpg files renamed as tbn + if (string.Equals(inputFormat, "tbn", StringComparison.OrdinalIgnoreCase)) + { + return new Tuple<string, DateTime>(originalImagePath, dateModified); + } + 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 cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png"; + var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension); var file = _fileSystem.GetFileInfo(outputPath); if (!file.Exists) @@ -748,12 +774,15 @@ namespace Emby.Drawing var imageInfo = item.GetImageInfo(imageType, imageIndex); - var result = await GetEnhancedImage(imageInfo, item, imageIndex, enhancers); + var inputImageSupportsTransparency = SupportsTransparency(imageInfo.Path); + + var result = await GetEnhancedImage(imageInfo, inputImageSupportsTransparency, item, imageIndex, enhancers); return result.Item1; } - private async Task<Tuple<string, DateTime>> GetEnhancedImage(ItemImageInfo image, + private async Task<Tuple<string, DateTime, bool>> GetEnhancedImage(ItemImageInfo image, + bool inputImageSupportsTransparency, IHasMetadata item, int imageIndex, List<IImageEnhancer> enhancers) @@ -767,20 +796,24 @@ namespace Emby.Drawing var cacheGuid = GetImageCacheTag(item, image, enhancers); // Enhance if we have enhancers - var ehnancedImagePath = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false); + var ehnancedImageInfo = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false); + + var ehnancedImagePath = ehnancedImageInfo.Item1; // If the path changed update dateModified if (!string.Equals(ehnancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase)) { - return GetResult(ehnancedImagePath); + var treatmentRequiresTransparency = ehnancedImageInfo.Item2; + + return new Tuple<string, DateTime, bool>(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency); } } catch (Exception ex) { - _logger.Error("Error enhancing image", ex); + _logger.ErrorException("Error enhancing image", ex); } - return new Tuple<string, DateTime>(originalImagePath, dateModified); + return new Tuple<string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency); } /// <summary> @@ -798,11 +831,11 @@ namespace Emby.Drawing /// or /// item /// </exception> - private async Task<string> GetEnhancedImageInternal(string originalImagePath, + private async Task<Tuple<string, bool>> GetEnhancedImageInternal(string originalImagePath, IHasMetadata item, ImageType imageType, int imageIndex, - IEnumerable<IImageEnhancer> supportedEnhancers, + List<IImageEnhancer> supportedEnhancers, string cacheGuid) { if (string.IsNullOrEmpty(originalImagePath)) @@ -815,13 +848,26 @@ namespace Emby.Drawing throw new ArgumentNullException("item"); } + var treatmentRequiresTransparency = false; + foreach (var enhancer in supportedEnhancers) + { + if (!treatmentRequiresTransparency) + { + treatmentRequiresTransparency = enhancer.GetEnhancedImageInfo(item, originalImagePath, imageType, imageIndex).RequiresTransparency; + } + } + // All enhanced images are saved as png to allow transparency - var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + ".png"); + var cacheExtension = _imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp) ? + ".webp" : + (treatmentRequiresTransparency ? ".png" : ".jpg"); + + var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + cacheExtension); // Check again in case of contention if (_fileSystem.FileExists(enhancedImagePath)) { - return enhancedImagePath; + return new Tuple<string, bool>(enhancedImagePath, treatmentRequiresTransparency); } _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(enhancedImagePath)); @@ -840,7 +886,7 @@ namespace Emby.Drawing } - return tmpPath; + return new Tuple<string, bool>(tmpPath, treatmentRequiresTransparency); } /// <summary> @@ -963,8 +1009,15 @@ namespace Emby.Drawing 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() |
