From 96a05276a627607e246fbc85e19f841ef8d24bf5 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sun, 27 Jul 2025 21:15:18 +0000 Subject: [PATCH] Removed all server side processing options from public endpoints for image gen --- Jellyfin.Api/Controllers/ImageController.cs | 159 +++++------------- .../Drawing/ImageProcessingOptions.cs | 2 + 2 files changed, 43 insertions(+), 118 deletions(-) diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index abda053d36..c175ce8b19 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; +using System.Drawing; using System.Globalization; using System.IO; using System.Linq; @@ -32,6 +33,15 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; +using ImageArgument = ( + int? Width, + int? Height, + int? FillWidth, + int? FillHeight, + int? Blur, + string? BackgroundColor, + string? ForegroundLayer, + int Quality); namespace Jellyfin.Api.Controllers; @@ -1457,20 +1467,6 @@ public class ImageController : BaseJellyfinApiController /// /// User id. /// Optional. Supply the cache tag from the item object to receive strong caching headers. - /// Determines the output format of the image - original,gif,jpg,png. - /// The maximum image width to return. - /// The maximum image height to return. - /// Optional. Percent to render for the percent played overlay. - /// Optional. Unplayed count overlay to render. - /// 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. Blur image. - /// Optional. Apply a background color for transparent images. - /// Optional. Apply a foreground layer on top of the image. - /// Image index. /// Image stream returned. /// User id not provided. /// Item not found. @@ -1486,21 +1482,7 @@ public class ImageController : BaseJellyfinApiController [ProducesImageFile] public async Task GetUserImage( [FromQuery] Guid? userId, - [FromQuery] string? tag, - [FromQuery] ImageFormat? format, - [FromQuery] int? maxWidth, - [FromQuery] int? maxHeight, - [FromQuery] double? percentPlayed, - [FromQuery] int? unplayedCount, - [FromQuery] int? width, - [FromQuery] int? height, - [FromQuery] int? quality, - [FromQuery] int? fillWidth, - [FromQuery] int? fillHeight, - [FromQuery] int? blur, - [FromQuery] string? backgroundColor, - [FromQuery] string? foregroundLayer, - [FromQuery] int? imageIndex) + [FromQuery] string? tag) { var requestUserId = userId ?? User.GetUserId(); if (requestUserId.IsEmpty()) @@ -1521,34 +1503,24 @@ public class ImageController : BaseJellyfinApiController DateModified = user.ProfileImage.LastModified }; - if (width.HasValue) - { - info.Width = width.Value; - } - - if (height.HasValue) - { - info.Height = height.Value; - } - return await GetImageInternal( user.Id, ImageType.Profile, - imageIndex, + null, tag, - format, - maxWidth, - maxHeight, - percentPlayed, - unplayedCount, - width, - height, - quality, - fillWidth, - fillHeight, - blur, - backgroundColor, - foregroundLayer, + ImageFormat.Jpg, + null, + null, + null, + null, + null, + null, + 90, + null, + null, + null, + null, + null, null, info) .ConfigureAwait(false); @@ -1607,21 +1579,7 @@ public class ImageController : BaseJellyfinApiController [FromQuery] int? imageIndex) => GetUserImage( userId, - tag, - format, - maxWidth, - maxHeight, - percentPlayed, - unplayedCount, - width, - height, - quality, - fillWidth, - fillHeight, - blur, - backgroundColor, - foregroundLayer, - imageIndex); + tag); /// /// Get user profile image. @@ -1676,55 +1634,19 @@ public class ImageController : BaseJellyfinApiController [FromQuery] string? foregroundLayer) => GetUserImage( userId, - tag, - format, - maxWidth, - maxHeight, - percentPlayed, - unplayedCount, - width, - height, - quality, - fillWidth, - fillHeight, - blur, - backgroundColor, - foregroundLayer, - imageIndex); + tag); /// /// Generates or gets the splashscreen. /// /// Supply the cache tag from the item object to receive strong caching headers. - /// Determines the output format of the image - original,gif,jpg,png. - /// The maximum image width to return. - /// The maximum image height to return. - /// The fixed image width to return. - /// The fixed image height to return. - /// Width of box to fill. - /// Height of box to fill. - /// Blur image. - /// Apply a background color for transparent images. - /// Apply a foreground layer on top of the image. - /// Quality setting, from 0-100. /// Splashscreen returned successfully. /// The splashscreen. [HttpGet("Branding/Splashscreen")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesImageFile] public async Task GetSplashscreen( - [FromQuery] string? tag, - [FromQuery] ImageFormat? format, - [FromQuery] int? maxWidth, - [FromQuery] int? maxHeight, - [FromQuery] int? width, - [FromQuery] int? height, - [FromQuery] int? fillWidth, - [FromQuery] int? fillHeight, - [FromQuery] int? blur, - [FromQuery] string? backgroundColor, - [FromQuery] string? foregroundLayer, - [FromQuery, Range(0, 100)] int quality = 90) + [FromQuery] string? tag) { var brandingOptions = _serverConfigurationManager.GetConfiguration("branding"); var isAdmin = User.IsInRole(Constants.UserRoles.Administrator); @@ -1749,7 +1671,7 @@ public class ImageController : BaseJellyfinApiController } } - var outputFormats = GetOutputFormats(format); + var outputFormats = GetOutputFormats(ImageFormat.Jpg); TimeSpan? cacheDuration = null; if (!string.IsNullOrEmpty(tag)) @@ -1763,16 +1685,16 @@ public class ImageController : BaseJellyfinApiController { Path = splashscreenPath }, - Height = height, - MaxHeight = maxHeight, - MaxWidth = maxWidth, - FillHeight = fillHeight, - FillWidth = fillWidth, - Quality = quality, - Width = width, - Blur = blur, - BackgroundColor = backgroundColor, - ForegroundLayer = foregroundLayer, + Height = null, + MaxHeight = null, + MaxWidth = null, + FillHeight = null, + FillWidth = null, + Quality = 90, + Width = null, + Blur = null, + BackgroundColor = null, + ForegroundLayer = null, SupportedOutputFormats = outputFormats }; @@ -1988,7 +1910,8 @@ public class ImageController : BaseJellyfinApiController Blur = blur, BackgroundColor = backgroundColor, ForegroundLayer = foregroundLayer, - SupportedOutputFormats = outputFormats + SupportedOutputFormats = outputFormats, + StrictCacheHandling = true }; return await GetImageResult( diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index 953cfe698e..02a4a8e18c 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -54,6 +54,8 @@ namespace MediaBrowser.Controller.Drawing public bool RequiresAutoOrientation { get; set; } + public bool StrictCacheHandling { get; set; } + private bool HasDefaultOptions(string originalImagePath) { return HasDefaultOptionsWithoutSize(originalImagePath) &&