diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index 978173d5a..7d952aa23 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using MediaBrowser.Common.Extensions;
@@ -171,11 +172,26 @@ namespace Emby.Drawing
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
- ImageDimensions newSize = ImageHelper.GetNewImageSize(options, null);
int quality = options.Quality;
ImageFormat outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency);
- string cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.Blur, options.BackgroundColor, options.ForegroundLayer);
+ string cacheFilePath = GetCacheFilePath(
+ originalImagePath,
+ options.Width,
+ options.Height,
+ options.MaxWidth,
+ options.MaxHeight,
+ options.FillWidth,
+ options.FillHeight,
+ quality,
+ dateModified,
+ outputFormat,
+ options.AddPlayedIndicator,
+ options.PercentPlayed,
+ options.UnplayedCount,
+ options.Blur,
+ options.BackgroundColor,
+ options.ForegroundLayer);
try
{
@@ -241,48 +257,111 @@ namespace Emby.Drawing
///
/// Gets the cache file path based on a set of parameters.
///
- private string GetCacheFilePath(string originalPath, ImageDimensions outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, int? blur, string backgroundColor, string foregroundLayer)
+ private string GetCacheFilePath(
+ string originalPath,
+ int? width,
+ int? height,
+ int? maxWidth,
+ int? maxHeight,
+ int? fillWidth,
+ int? fillHeight,
+ int quality,
+ DateTime dateModified,
+ ImageFormat format,
+ bool addPlayedIndicator,
+ double percentPlayed,
+ int? unwatchedCount,
+ int? blur,
+ string backgroundColor,
+ string foregroundLayer)
{
- var filename = originalPath
- + "width=" + outputSize.Width
- + "height=" + outputSize.Height
- + "quality=" + quality
- + "datemodified=" + dateModified.Ticks
- + "f=" + format;
+ var filename = new StringBuilder(256);
+ filename.Append(originalPath);
+
+ filename.Append(",quality=");
+ filename.Append(quality);
+
+ filename.Append(",datemodified=");
+ filename.Append(dateModified.Ticks);
+
+ filename.Append(",f=");
+ filename.Append(format);
+
+ if (width.HasValue)
+ {
+ filename.Append(",width=");
+ filename.Append(width.Value);
+ }
+
+ if (height.HasValue)
+ {
+ filename.Append(",height=");
+ filename.Append(height.Value);
+ }
+
+ if (maxWidth.HasValue)
+ {
+ filename.Append(",maxwidth=");
+ filename.Append(maxWidth.Value);
+ }
+
+ if (maxHeight.HasValue)
+ {
+ filename.Append(",maxheight=");
+ filename.Append(maxHeight.Value);
+ }
+
+ if (fillWidth.HasValue)
+ {
+ filename.Append(",fillwidth=");
+ filename.Append(fillWidth.Value);
+ }
+
+ if (fillHeight.HasValue)
+ {
+ filename.Append(",fillheight=");
+ filename.Append(fillHeight.Value);
+ }
if (addPlayedIndicator)
{
- filename += "pl=true";
+ filename.Append(",pl=true");
}
if (percentPlayed > 0)
{
- filename += "p=" + percentPlayed;
+ filename.Append(",p=");
+ filename.Append(percentPlayed);
}
if (unwatchedCount.HasValue)
{
- filename += "p=" + unwatchedCount.Value;
+ filename.Append(",p=");
+ filename.Append(unwatchedCount.Value);
}
if (blur.HasValue)
{
- filename += "blur=" + blur.Value;
+ filename.Append(",blur=");
+ filename.Append(blur.Value);
}
if (!string.IsNullOrEmpty(backgroundColor))
{
- filename += "b=" + backgroundColor;
+ filename.Append(",b=");
+ filename.Append(backgroundColor);
}
if (!string.IsNullOrEmpty(foregroundLayer))
{
- filename += "fl=" + foregroundLayer;
+ filename.Append(",fl=");
+ filename.Append(foregroundLayer);
}
- filename += "v=" + Version;
+ filename.Append(",v=");
+ filename.Append(Version);
- return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLowerInvariant());
+ return GetCachePath(ResizedImageCachePath, filename.ToString(), "." + format.ToString().ToLowerInvariant());
}
///
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 2119e8e2c..55c2fe735 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -490,6 +490,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Supply the cache tag from the item object to receive strong caching headers.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. The of the returned image.
@@ -519,6 +521,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] string? tag,
[FromQuery] bool? cropWhitespace,
[FromQuery] ImageFormat? format,
@@ -549,6 +553,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -570,6 +576,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Supply the cache tag from the item object to receive strong caching headers.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. The of the returned image.
@@ -599,6 +607,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] string? tag,
[FromQuery] bool? cropWhitespace,
[FromQuery] ImageFormat? format,
@@ -628,6 +638,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -648,6 +660,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Supply the cache tag from the item object to receive strong caching headers.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Determines the output format of the image - original,gif,jpg,png.
@@ -677,6 +691,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromRoute, Required] string tag,
[FromQuery] bool? cropWhitespace,
[FromRoute, Required] ImageFormat format,
@@ -707,6 +723,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -731,6 +749,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -760,6 +780,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -786,6 +808,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -810,6 +834,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -839,6 +865,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -865,6 +893,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -890,6 +920,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -919,6 +951,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -944,6 +978,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -968,6 +1004,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -997,6 +1035,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1023,6 +1063,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1048,6 +1090,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1077,6 +1121,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1102,6 +1148,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1126,6 +1174,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1155,6 +1205,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1181,6 +1233,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1206,6 +1260,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1235,6 +1291,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1260,6 +1318,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1284,6 +1344,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1313,6 +1375,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1339,6 +1403,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1364,6 +1430,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1393,6 +1461,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1418,6 +1488,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1442,6 +1514,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1471,6 +1545,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1514,6 +1590,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1540,6 +1618,8 @@ namespace Jellyfin.Api.Controllers
/// The fixed image width to return.
/// The fixed image height to return.
/// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.
+ /// Width of box to fill.
+ /// Height of box to fill.
/// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.
/// Optional. Add a played indicator.
/// Optional. Blur image.
@@ -1569,6 +1649,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width,
[FromQuery] int? height,
[FromQuery] int? quality,
+ [FromQuery] int? fillWidth,
+ [FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur,
@@ -1611,6 +1693,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1695,6 +1779,8 @@ namespace Jellyfin.Api.Controllers
int? width,
int? height,
int? quality,
+ int? fillWidth,
+ int? fillHeight,
bool? cropWhitespace, // TODO: Remove
bool? addPlayedIndicator,
int? blur,
@@ -1758,11 +1844,13 @@ namespace Jellyfin.Api.Controllers
item,
itemId,
imageIndex,
- height,
- maxHeight,
- maxWidth,
- quality,
width,
+ height,
+ maxWidth,
+ maxHeight,
+ fillWidth,
+ fillHeight,
+ quality,
addPlayedIndicator,
percentPlayed,
unplayedCount,
@@ -1856,11 +1944,13 @@ namespace Jellyfin.Api.Controllers
BaseItem? item,
Guid itemId,
int? index,
- int? height,
- int? maxHeight,
- int? maxWidth,
- int? quality,
int? width,
+ int? height,
+ int? maxWidth,
+ int? maxHeight,
+ int? fillWidth,
+ int? fillHeight,
+ int? quality,
bool? addPlayedIndicator,
double? percentPlayed,
int? unplayedCount,
@@ -1887,6 +1977,8 @@ namespace Jellyfin.Api.Controllers
ItemId = itemId,
MaxHeight = maxHeight,
MaxWidth = maxWidth,
+ FillHeight = fillHeight,
+ FillWidth = fillWidth,
Quality = quality ?? 100,
Width = width,
AddPlayedIndicator = addPlayedIndicator ?? false,
diff --git a/MediaBrowser.Controller/Drawing/ImageHelper.cs b/MediaBrowser.Controller/Drawing/ImageHelper.cs
index 87c28d577..181f8e905 100644
--- a/MediaBrowser.Controller/Drawing/ImageHelper.cs
+++ b/MediaBrowser.Controller/Drawing/ImageHelper.cs
@@ -1,4 +1,5 @@
#pragma warning disable CS1591
+#nullable enable
using System;
using MediaBrowser.Controller.Entities;
@@ -9,67 +10,12 @@ namespace MediaBrowser.Controller.Drawing
{
public static class ImageHelper
{
- public static ImageDimensions GetNewImageSize(ImageProcessingOptions options, ImageDimensions? originalImageSize)
+ public static ImageDimensions GetNewImageSize(ImageProcessingOptions options, ImageDimensions 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);
- }
-
- private static ImageDimensions GetSizeEstimate(ImageProcessingOptions options)
- {
- if (options.Width.HasValue && options.Height.HasValue)
- {
- return new ImageDimensions(options.Width.Value, options.Height.Value);
- }
-
- double aspect = GetEstimatedAspectRatio(options.Image.Type, options.Item);
-
- int? width = options.Width ?? options.MaxWidth;
-
- if (width.HasValue)
- {
- int heightValue = Convert.ToInt32((double)width.Value / aspect);
- return new ImageDimensions(width.Value, heightValue);
- }
-
- var height = options.Height ?? options.MaxHeight ?? 200;
- int widthValue = Convert.ToInt32(aspect * height);
- return new ImageDimensions(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:
- case ImageType.Profile:
- return 1;
- case ImageType.Logo:
- return 2.58;
- case ImageType.Primary:
- double defaultPrimaryImageAspectRatio = item.GetDefaultPrimaryImageAspectRatio();
- return defaultPrimaryImageAspectRatio > 0 ? defaultPrimaryImageAspectRatio : 2.0 / 3;
- default:
- return 1;
- }
+ // Determine the output size based on incoming parameters
+ var newSize = DrawingUtils.Resize(originalImageSize, options.Width ?? 0, options.Height ?? 0, options.MaxWidth ?? 0, options.MaxHeight ?? 0);
+ newSize = DrawingUtils.ResizeFill(newSize, options.FillWidth, options.FillHeight);
+ return newSize;
}
}
}
diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
index 22de9a43e..230a0af60 100644
--- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
+++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
@@ -32,6 +32,10 @@ namespace MediaBrowser.Controller.Drawing
public int? MaxHeight { get; set; }
+ public int? FillWidth { get; set; }
+
+ public int? FillHeight { get; set; }
+
public int Quality { get; set; }
public IReadOnlyCollection SupportedOutputFormats { get; set; }
@@ -93,6 +97,11 @@ namespace MediaBrowser.Controller.Drawing
return false;
}
+ if (sizeValue.Width > FillWidth || sizeValue.Height > FillHeight)
+ {
+ return false;
+ }
+
return true;
}
diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs
index 1512c5233..556792768 100644
--- a/MediaBrowser.Model/Drawing/DrawingUtils.cs
+++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs
@@ -57,6 +57,52 @@ namespace MediaBrowser.Model.Drawing
return new ImageDimensions(newWidth, newHeight);
}
+ ///
+ /// Scale down to fill box.
+ /// Returns original size if both width and height are null or zero.
+ ///
+ /// The original size object.
+ /// A new fixed width, if desired.
+ /// A new fixed height, if desired.
+ /// A new size object or size.
+ public static ImageDimensions ResizeFill(
+ ImageDimensions size,
+ int? fillWidth,
+ int? fillHeight)
+ {
+ // Return original size if input is invalid.
+ if ((fillWidth == null || fillWidth == 0)
+ && (fillHeight == null || fillHeight == 0))
+ {
+ return size;
+ }
+
+ if (fillWidth == null || fillWidth == 0)
+ {
+ fillWidth = 1;
+ }
+
+ if (fillHeight == null || fillHeight == 0)
+ {
+ fillHeight = 1;
+ }
+
+ double widthRatio = size.Width / (double)fillWidth;
+ double heightRatio = size.Height / (double)fillHeight;
+ double scaleRatio = Math.Min(widthRatio, heightRatio);
+
+ // Clamp to current size.
+ if (scaleRatio < 1)
+ {
+ return size;
+ }
+
+ int newWidth = Convert.ToInt32(Math.Ceiling(size.Width / scaleRatio));
+ int newHeight = Convert.ToInt32(Math.Ceiling(size.Height / scaleRatio));
+
+ return new ImageDimensions(newWidth, newHeight);
+ }
+
///
/// Gets the new width.
///