diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index 8a2301d2d6..c8034dd451 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
{
@@ -246,48 +262,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 c1dd6a1e02..6fe449d33d 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -480,6 +480,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.
@@ -509,6 +511,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,
@@ -539,6 +543,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -560,6 +566,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.
@@ -589,6 +597,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,
@@ -618,6 +628,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -638,6 +650,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.
@@ -667,6 +681,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,
@@ -697,6 +713,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -721,6 +739,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.
@@ -750,6 +770,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,
@@ -776,6 +798,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -800,6 +824,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.
@@ -829,6 +855,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,
@@ -855,6 +883,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -880,6 +910,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.
@@ -909,6 +941,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,
@@ -934,6 +968,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -958,6 +994,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.
@@ -987,6 +1025,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,
@@ -1013,6 +1053,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1038,6 +1080,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.
@@ -1067,6 +1111,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,
@@ -1092,6 +1138,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1116,6 +1164,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.
@@ -1145,6 +1195,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,
@@ -1171,6 +1223,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1196,6 +1250,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.
@@ -1225,6 +1281,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,
@@ -1250,6 +1308,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1274,6 +1334,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.
@@ -1303,6 +1365,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,
@@ -1329,6 +1393,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1354,6 +1420,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.
@@ -1383,6 +1451,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,
@@ -1408,6 +1478,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1432,6 +1504,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.
@@ -1461,6 +1535,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,
@@ -1504,6 +1580,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1530,6 +1608,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.
@@ -1559,6 +1639,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,
@@ -1601,6 +1683,8 @@ namespace Jellyfin.Api.Controllers
width,
height,
quality,
+ fillWidth,
+ fillHeight,
cropWhitespace,
addPlayedIndicator,
blur,
@@ -1685,6 +1769,8 @@ namespace Jellyfin.Api.Controllers
int? width,
int? height,
int? quality,
+ int? fillWidth,
+ int? fillHeight,
bool? cropWhitespace,
bool? addPlayedIndicator,
int? blur,
@@ -1748,11 +1834,13 @@ namespace Jellyfin.Api.Controllers
item,
itemId,
imageIndex,
+ width,
height,
- maxHeight,
maxWidth,
+ maxHeight,
+ fillWidth,
+ fillHeight,
quality,
- width,
addPlayedIndicator,
percentPlayed,
unplayedCount,
@@ -1847,11 +1935,13 @@ namespace Jellyfin.Api.Controllers
BaseItem? item,
Guid itemId,
int? index,
+ int? width,
int? height,
- int? maxHeight,
int? maxWidth,
+ int? maxHeight,
+ int? fillWidth,
+ int? fillHeight,
int? quality,
- int? width,
bool? addPlayedIndicator,
double? percentPlayed,
int? unplayedCount,
@@ -1880,6 +1970,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 87c28d5773..181f8e905f 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 22105b7d79..6ae3a602ae 100644
--- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
+++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
@@ -34,6 +34,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; }
@@ -95,6 +99,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 1512c52337..5567927682 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.
///