Merge pull request #5556 from oddstr13/image-fill-resize

This commit is contained in:
Bond-009 2021-04-11 13:34:22 +02:00 committed by GitHub
commit 790f7430aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 257 additions and 85 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Data.Entities; using Jellyfin.Data.Entities;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
@ -171,11 +172,26 @@ namespace Emby.Drawing
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
} }
ImageDimensions newSize = ImageHelper.GetNewImageSize(options, null);
int quality = options.Quality; int quality = options.Quality;
ImageFormat outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency); 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 try
{ {
@ -241,48 +257,111 @@ namespace Emby.Drawing
/// <summary> /// <summary>
/// Gets the cache file path based on a set of parameters. /// Gets the cache file path based on a set of parameters.
/// </summary> /// </summary>
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 var filename = new StringBuilder(256);
+ "width=" + outputSize.Width filename.Append(originalPath);
+ "height=" + outputSize.Height
+ "quality=" + quality filename.Append(",quality=");
+ "datemodified=" + dateModified.Ticks filename.Append(quality);
+ "f=" + format;
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) if (addPlayedIndicator)
{ {
filename += "pl=true"; filename.Append(",pl=true");
} }
if (percentPlayed > 0) if (percentPlayed > 0)
{ {
filename += "p=" + percentPlayed; filename.Append(",p=");
filename.Append(percentPlayed);
} }
if (unwatchedCount.HasValue) if (unwatchedCount.HasValue)
{ {
filename += "p=" + unwatchedCount.Value; filename.Append(",p=");
filename.Append(unwatchedCount.Value);
} }
if (blur.HasValue) if (blur.HasValue)
{ {
filename += "blur=" + blur.Value; filename.Append(",blur=");
filename.Append(blur.Value);
} }
if (!string.IsNullOrEmpty(backgroundColor)) if (!string.IsNullOrEmpty(backgroundColor))
{ {
filename += "b=" + backgroundColor; filename.Append(",b=");
filename.Append(backgroundColor);
} }
if (!string.IsNullOrEmpty(foregroundLayer)) 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());
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -490,6 +490,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param> /// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="format">Optional. The <see cref="ImageFormat"/> of the returned image.</param> /// <param name="format">Optional. The <see cref="ImageFormat"/> of the returned image.</param>
@ -519,6 +521,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] ImageFormat? format, [FromQuery] ImageFormat? format,
@ -549,6 +553,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -570,6 +576,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param> /// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="format">Optional. The <see cref="ImageFormat"/> of the returned image.</param> /// <param name="format">Optional. The <see cref="ImageFormat"/> of the returned image.</param>
@ -599,6 +607,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] string? tag, [FromQuery] string? tag,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] ImageFormat? format, [FromQuery] ImageFormat? format,
@ -628,6 +638,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -648,6 +660,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param> /// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="format">Determines the output format of the image - original,gif,jpg,png.</param> /// <param name="format">Determines the output format of the image - original,gif,jpg,png.</param>
@ -677,6 +691,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromRoute, Required] string tag, [FromRoute, Required] string tag,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromRoute, Required] ImageFormat format, [FromRoute, Required] ImageFormat format,
@ -707,6 +723,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -731,6 +749,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -760,6 +780,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -786,6 +808,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -810,6 +834,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -839,6 +865,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -865,6 +893,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -890,6 +920,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -919,6 +951,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -944,6 +978,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -968,6 +1004,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -997,6 +1035,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1023,6 +1063,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1048,6 +1090,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1077,6 +1121,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1102,6 +1148,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1126,6 +1174,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1155,6 +1205,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1181,6 +1233,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1206,6 +1260,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1235,6 +1291,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1260,6 +1318,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1284,6 +1344,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1313,6 +1375,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1339,6 +1403,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1364,6 +1430,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1393,6 +1461,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1418,6 +1488,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1442,6 +1514,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1471,6 +1545,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1514,6 +1590,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1540,6 +1618,8 @@ namespace Jellyfin.Api.Controllers
/// <param name="width">The fixed image width to return.</param> /// <param name="width">The fixed image width to return.</param>
/// <param name="height">The fixed image height to return.</param> /// <param name="height">The fixed image height to return.</param>
/// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param>
/// <param name="fillWidth">Width of box to fill.</param>
/// <param name="fillHeight">Height of box to fill.</param>
/// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param> /// <param name="cropWhitespace">Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art.</param>
/// <param name="addPlayedIndicator">Optional. Add a played indicator.</param> /// <param name="addPlayedIndicator">Optional. Add a played indicator.</param>
/// <param name="blur">Optional. Blur image.</param> /// <param name="blur">Optional. Blur image.</param>
@ -1569,6 +1649,8 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? width, [FromQuery] int? width,
[FromQuery] int? height, [FromQuery] int? height,
[FromQuery] int? quality, [FromQuery] int? quality,
[FromQuery] int? fillWidth,
[FromQuery] int? fillHeight,
[FromQuery] bool? cropWhitespace, [FromQuery] bool? cropWhitespace,
[FromQuery] bool? addPlayedIndicator, [FromQuery] bool? addPlayedIndicator,
[FromQuery] int? blur, [FromQuery] int? blur,
@ -1611,6 +1693,8 @@ namespace Jellyfin.Api.Controllers
width, width,
height, height,
quality, quality,
fillWidth,
fillHeight,
cropWhitespace, cropWhitespace,
addPlayedIndicator, addPlayedIndicator,
blur, blur,
@ -1695,6 +1779,8 @@ namespace Jellyfin.Api.Controllers
int? width, int? width,
int? height, int? height,
int? quality, int? quality,
int? fillWidth,
int? fillHeight,
bool? cropWhitespace, // TODO: Remove bool? cropWhitespace, // TODO: Remove
bool? addPlayedIndicator, bool? addPlayedIndicator,
int? blur, int? blur,
@ -1758,11 +1844,13 @@ namespace Jellyfin.Api.Controllers
item, item,
itemId, itemId,
imageIndex, imageIndex,
height,
maxHeight,
maxWidth,
quality,
width, width,
height,
maxWidth,
maxHeight,
fillWidth,
fillHeight,
quality,
addPlayedIndicator, addPlayedIndicator,
percentPlayed, percentPlayed,
unplayedCount, unplayedCount,
@ -1856,11 +1944,13 @@ namespace Jellyfin.Api.Controllers
BaseItem? item, BaseItem? item,
Guid itemId, Guid itemId,
int? index, int? index,
int? height,
int? maxHeight,
int? maxWidth,
int? quality,
int? width, int? width,
int? height,
int? maxWidth,
int? maxHeight,
int? fillWidth,
int? fillHeight,
int? quality,
bool? addPlayedIndicator, bool? addPlayedIndicator,
double? percentPlayed, double? percentPlayed,
int? unplayedCount, int? unplayedCount,
@ -1887,6 +1977,8 @@ namespace Jellyfin.Api.Controllers
ItemId = itemId, ItemId = itemId,
MaxHeight = maxHeight, MaxHeight = maxHeight,
MaxWidth = maxWidth, MaxWidth = maxWidth,
FillHeight = fillHeight,
FillWidth = fillWidth,
Quality = quality ?? 100, Quality = quality ?? 100,
Width = width, Width = width,
AddPlayedIndicator = addPlayedIndicator ?? false, AddPlayedIndicator = addPlayedIndicator ?? false,

View File

@ -1,4 +1,5 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
#nullable enable
using System; using System;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -9,67 +10,12 @@ namespace MediaBrowser.Controller.Drawing
{ {
public static class ImageHelper 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, options.Width ?? 0, options.Height ?? 0, options.MaxWidth ?? 0, options.MaxHeight ?? 0);
// Determine the output size based on incoming parameters newSize = DrawingUtils.ResizeFill(newSize, options.FillWidth, options.FillHeight);
var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width ?? 0, options.Height ?? 0, options.MaxWidth ?? 0, options.MaxHeight ?? 0); return newSize;
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;
}
} }
} }
} }

View File

@ -32,6 +32,10 @@ namespace MediaBrowser.Controller.Drawing
public int? MaxHeight { get; set; } public int? MaxHeight { get; set; }
public int? FillWidth { get; set; }
public int? FillHeight { get; set; }
public int Quality { get; set; } public int Quality { get; set; }
public IReadOnlyCollection<ImageFormat> SupportedOutputFormats { get; set; } public IReadOnlyCollection<ImageFormat> SupportedOutputFormats { get; set; }
@ -93,6 +97,11 @@ namespace MediaBrowser.Controller.Drawing
return false; return false;
} }
if (sizeValue.Width > FillWidth || sizeValue.Height > FillHeight)
{
return false;
}
return true; return true;
} }

View File

@ -57,6 +57,52 @@ namespace MediaBrowser.Model.Drawing
return new ImageDimensions(newWidth, newHeight); return new ImageDimensions(newWidth, newHeight);
} }
/// <summary>
/// Scale down to fill box.
/// Returns original size if both width and height are null or zero.
/// </summary>
/// <param name="size">The original size object.</param>
/// <param name="fillWidth">A new fixed width, if desired.</param>
/// <param name="fillHeight">A new fixed height, if desired.</param>
/// <returns>A new size object or size.</returns>
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);
}
/// <summary> /// <summary>
/// Gets the new width. /// Gets the new width.
/// </summary> /// </summary>