diff options
Diffstat (limited to 'MediaBrowser.Controller/Drawing')
| -rw-r--r-- | MediaBrowser.Controller/Drawing/IImageEncoder.cs | 49 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/IImageProcessor.cs | 118 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageCollageOptions.cs | 27 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageHelper.cs | 72 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs | 114 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageProcessorExtensions.cs | 25 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageStream.cs | 28 |
7 files changed, 433 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs new file mode 100644 index 000000000..757448eb2 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs @@ -0,0 +1,49 @@ +using System; +using MediaBrowser.Model.Drawing; + +namespace MediaBrowser.Controller.Drawing +{ + public interface IImageEncoder + { + /// <summary> + /// Gets the supported input formats. + /// </summary> + /// <value>The supported input formats.</value> + string[] SupportedInputFormats { get; } + /// <summary> + /// Gets the supported output formats. + /// </summary> + /// <value>The supported output formats.</value> + ImageFormat[] SupportedOutputFormats { get; } + + /// <summary> + /// Encodes the image. + /// </summary> + string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + + /// <summary> + /// Creates the image collage. + /// </summary> + /// <param name="options">The options.</param> + void CreateImageCollage(ImageCollageOptions options); + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Gets a value indicating whether [supports image collage creation]. + /// </summary> + /// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value> + bool SupportsImageCollageCreation { get; } + + /// <summary> + /// Gets a value indicating whether [supports image encoding]. + /// </summary> + /// <value><c>true</c> if [supports image encoding]; otherwise, <c>false</c>.</value> + bool SupportsImageEncoding { get; } + + ImageSize GetImageSize(string path); + } +} diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs new file mode 100644 index 000000000..fdf10e223 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -0,0 +1,118 @@ +using System; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Drawing +{ + /// <summary> + /// Interface IImageProcessor + /// </summary> + public interface IImageProcessor + { + /// <summary> + /// Gets the supported input formats. + /// </summary> + /// <value>The supported input formats.</value> + string[] SupportedInputFormats { get; } + + /// <summary> + /// Gets the image enhancers. + /// </summary> + /// <value>The image enhancers.</value> + IImageEnhancer[] ImageEnhancers { get; } + + ImageSize GetImageSize(string path); + + /// <summary> + /// Gets the size of the image. + /// </summary> + /// <param name="info">The information.</param> + /// <returns>ImageSize.</returns> + ImageSize GetImageSize(BaseItem item, ItemImageInfo info); + + ImageSize GetImageSize(BaseItem item, ItemImageInfo info, bool allowSlowMethods, bool updateItem); + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="enhancers">The enhancers.</param> + void AddParts(IEnumerable<IImageEnhancer> enhancers); + + /// <summary> + /// Gets the supported enhancers. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="imageType">Type of the image.</param> + /// <returns>IEnumerable{IImageEnhancer}.</returns> + IImageEnhancer[] GetSupportedEnhancers(BaseItem item, ImageType imageType); + + /// <summary> + /// Gets the image cache tag. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="image">The image.</param> + /// <returns>Guid.</returns> + string GetImageCacheTag(BaseItem item, ItemImageInfo image); + string GetImageCacheTag(BaseItem item, ChapterInfo info); + + /// <summary> + /// Gets the image cache tag. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="image">The image.</param> + /// <param name="imageEnhancers">The image enhancers.</param> + /// <returns>Guid.</returns> + string GetImageCacheTag(BaseItem item, ItemImageInfo image, IImageEnhancer[] imageEnhancers); + + /// <summary> + /// Processes the image. + /// </summary> + /// <param name="options">The options.</param> + /// <param name="toStream">To stream.</param> + /// <returns>Task.</returns> + Task ProcessImage(ImageProcessingOptions options, Stream toStream); + + /// <summary> + /// Processes the image. + /// </summary> + /// <param name="options">The options.</param> + /// <returns>Task.</returns> + Task<Tuple<string, string, DateTime>> ProcessImage(ImageProcessingOptions options); + + /// <summary> + /// Gets the enhanced image. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="imageType">Type of the image.</param> + /// <param name="imageIndex">Index of the image.</param> + /// <returns>Task{System.String}.</returns> + Task<string> GetEnhancedImage(BaseItem item, ImageType imageType, int imageIndex); + + /// <summary> + /// Gets the supported image output formats. + /// </summary> + /// <returns>ImageOutputFormat[].</returns> + ImageFormat[] GetSupportedImageOutputFormats(); + + /// <summary> + /// Creates the image collage. + /// </summary> + /// <param name="options">The options.</param> + void CreateImageCollage(ImageCollageOptions options); + + /// <summary> + /// Gets a value indicating whether [supports image collage creation]. + /// </summary> + /// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value> + bool SupportsImageCollageCreation { get; } + + IImageEncoder ImageEncoder { get; set; } + + bool SupportsTransparency(string path); + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs b/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs new file mode 100644 index 000000000..92a7f5ac9 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageCollageOptions.cs @@ -0,0 +1,27 @@ + +namespace MediaBrowser.Controller.Drawing +{ + public class ImageCollageOptions + { + /// <summary> + /// Gets or sets the input paths. + /// </summary> + /// <value>The input paths.</value> + public string[] InputPaths { get; set; } + /// <summary> + /// Gets or sets the output path. + /// </summary> + /// <value>The output path.</value> + public string OutputPath { get; set; } + /// <summary> + /// Gets or sets the width. + /// </summary> + /// <value>The width.</value> + public int Width { get; set; } + /// <summary> + /// Gets or sets the height. + /// </summary> + /// <value>The height.</value> + public int Height { get; set; } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageHelper.cs b/MediaBrowser.Controller/Drawing/ImageHelper.cs new file mode 100644 index 000000000..6fb9f256e --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageHelper.cs @@ -0,0 +1,72 @@ +using System; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Controller.Drawing +{ + public static class ImageHelper + { + public static ImageSize GetNewImageSize(ImageProcessingOptions options, ImageSize? originalImageSize) + { + if (originalImageSize.HasValue) + { + // Determine the output size based on incoming parameters + var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width ?? 0, options.Height ?? 0, options.MaxWidth ?? 0, options.MaxHeight ?? 0); + + return newSize; + } + return GetSizeEstimate(options); + } + + public static IImageProcessor ImageProcessor { get; set; } + + private static ImageSize GetSizeEstimate(ImageProcessingOptions options) + { + if (options.Width.HasValue && options.Height.HasValue) + { + return new ImageSize(options.Width.Value, options.Height.Value); + } + + var aspect = GetEstimatedAspectRatio(options.Image.Type, options.Item); + + var width = options.Width ?? options.MaxWidth; + + if (width.HasValue) + { + var heightValue = width.Value / aspect; + return new ImageSize(width.Value, heightValue); + } + + var height = options.Height ?? options.MaxHeight ?? 200; + var widthValue = aspect * height; + return new ImageSize(widthValue, height); + } + + private static double GetEstimatedAspectRatio(ImageType type, BaseItem item) + { + switch (type) + { + case ImageType.Art: + case ImageType.Backdrop: + case ImageType.Chapter: + case ImageType.Screenshot: + case ImageType.Thumb: + return 1.78; + case ImageType.Banner: + return 5.4; + case ImageType.Box: + case ImageType.BoxRear: + case ImageType.Disc: + case ImageType.Menu: + return 1; + case ImageType.Logo: + return 2.58; + case ImageType.Primary: + return item.GetDefaultPrimaryImageAspectRatio(); + default: + return 1; + } + } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs new file mode 100644 index 000000000..ffc3e6cc0 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -0,0 +1,114 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Drawing; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Controller.Drawing +{ + public class ImageProcessingOptions + { + public ImageProcessingOptions() + { + RequiresAutoOrientation = true; + } + + public Guid ItemId { get; set; } + public BaseItem Item { get; set; } + + public ItemImageInfo Image { get; set; } + + public int ImageIndex { get; set; } + + public bool CropWhiteSpace { get; set; } + + public int? Width { get; set; } + + public int? Height { get; set; } + + public int? MaxWidth { get; set; } + + public int? MaxHeight { get; set; } + + public int Quality { get; set; } + + public IImageEnhancer[] Enhancers { get; set; } + + public ImageFormat[] SupportedOutputFormats { get; set; } + + public bool AddPlayedIndicator { get; set; } + + public int? UnplayedCount { get; set; } + public int? Blur { get; set; } + + public double PercentPlayed { get; set; } + + public string BackgroundColor { get; set; } + public string ForegroundLayer { get; set; } + public bool RequiresAutoOrientation { get; set; } + + private bool HasDefaultOptions(string originalImagePath) + { + return HasDefaultOptionsWithoutSize(originalImagePath) && + !Width.HasValue && + !Height.HasValue && + !MaxWidth.HasValue && + !MaxHeight.HasValue; + } + + public bool HasDefaultOptions(string originalImagePath, ImageSize? size) + { + if (!size.HasValue) + { + return HasDefaultOptions(originalImagePath); + } + + if (!HasDefaultOptionsWithoutSize(originalImagePath)) + { + return false; + } + + var sizeValue = size.Value; + + if (Width.HasValue && !sizeValue.Width.Equals(Width.Value)) + { + return false; + } + if (Height.HasValue && !sizeValue.Height.Equals(Height.Value)) + { + return false; + } + if (MaxWidth.HasValue && sizeValue.Width > MaxWidth.Value) + { + return false; + } + if (MaxHeight.HasValue && sizeValue.Height > MaxHeight.Value) + { + return false; + } + + return true; + } + + private bool HasDefaultOptionsWithoutSize(string originalImagePath) + { + return (Quality >= 90) && + IsFormatSupported(originalImagePath) && + !AddPlayedIndicator && + PercentPlayed.Equals(0) && + !UnplayedCount.HasValue && + !Blur.HasValue && + !CropWhiteSpace && + string.IsNullOrEmpty(BackgroundColor) && + string.IsNullOrEmpty(ForegroundLayer); + } + + private bool IsFormatSupported(string originalImagePath) + { + var ext = Path.GetExtension(originalImagePath); + return SupportedOutputFormats.Any(outputFormat => string.Equals(ext, "." + outputFormat, StringComparison.OrdinalIgnoreCase)); + } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageProcessorExtensions.cs b/MediaBrowser.Controller/Drawing/ImageProcessorExtensions.cs new file mode 100644 index 000000000..948219bf5 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageProcessorExtensions.cs @@ -0,0 +1,25 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Controller.Drawing +{ + public static class ImageProcessorExtensions + { + public static string GetImageCacheTag(this IImageProcessor processor, BaseItem item, ImageType imageType) + { + return processor.GetImageCacheTag(item, imageType, 0); + } + + public static string GetImageCacheTag(this IImageProcessor processor, BaseItem item, ImageType imageType, int imageIndex) + { + var imageInfo = item.GetImageInfo(imageType, imageIndex); + + if (imageInfo == null) + { + return null; + } + + return processor.GetImageCacheTag(item, imageInfo); + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Drawing/ImageStream.cs b/MediaBrowser.Controller/Drawing/ImageStream.cs new file mode 100644 index 000000000..353abaca3 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/ImageStream.cs @@ -0,0 +1,28 @@ +using MediaBrowser.Model.Drawing; +using System; +using System.IO; + +namespace MediaBrowser.Controller.Drawing +{ + public class ImageStream : IDisposable + { + /// <summary> + /// Gets or sets the stream. + /// </summary> + /// <value>The stream.</value> + public Stream Stream { get; set; } + /// <summary> + /// Gets or sets the format. + /// </summary> + /// <value>The format.</value> + public ImageFormat Format { get; set; } + + public void Dispose() + { + if (Stream != null) + { + Stream.Dispose(); + } + } + } +} |
