diff options
| author | JPVenson <ger-delta-07@hotmail.de> | 2024-10-17 15:35:03 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-17 07:35:03 -0600 |
| commit | 8b4fa42e49e305df544dd12fedb7a55a5bdaf74b (patch) | |
| tree | e3c4582e16f75e252d008a05207fc14ed4863d64 /src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs | |
| parent | 4251cbc27799f50eb58fda6fb30f735bbc781a0d (diff) | |
Ensure Skia images are always disposed (#12786)
Diffstat (limited to 'src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs')
| -rw-r--r-- | src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs | 167 |
1 files changed, 96 insertions, 71 deletions
diff --git a/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs b/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs index 9905566230..7af77758b4 100644 --- a/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs +++ b/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Microsoft.Extensions.Logging; using SkiaSharp; namespace Jellyfin.Drawing.Skia; @@ -18,14 +19,17 @@ public class SplashscreenBuilder private const int Spacing = 20; private readonly SkiaEncoder _skiaEncoder; + private readonly ILogger _logger; /// <summary> /// Initializes a new instance of the <see cref="SplashscreenBuilder"/> class. /// </summary> /// <param name="skiaEncoder">The SkiaEncoder.</param> - public SplashscreenBuilder(SkiaEncoder skiaEncoder) + /// <param name="logger">The logger.</param> + public SplashscreenBuilder(SkiaEncoder skiaEncoder, ILogger logger) { _skiaEncoder = skiaEncoder; + _logger = logger; } /// <summary> @@ -55,65 +59,76 @@ public class SplashscreenBuilder var posterIndex = 0; var backdropIndex = 0; - var bitmap = new SKBitmap(WallWidth, WallHeight); - using var canvas = new SKCanvas(bitmap); - canvas.Clear(SKColors.Black); - - int posterHeight = WallHeight / 6; - - for (int i = 0; i < Rows; i++) + SKBitmap? bitmap = null; + try { - int imageCounter = Random.Shared.Next(0, 5); - int currentWidthPos = i * 75; - int currentHeight = i * (posterHeight + Spacing); - - while (currentWidthPos < WallWidth) - { - SKBitmap? currentImage; - - switch (imageCounter) - { - case 0: - case 2: - case 3: - currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, posters, posterIndex, out int newPosterIndex); - posterIndex = newPosterIndex; - break; - default: - currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, backdrops, backdropIndex, out int newBackdropIndex); - backdropIndex = newBackdropIndex; - break; - } - - if (currentImage is null) - { - throw new ArgumentException("Not enough valid pictures provided to create a splashscreen!"); - } - - // resize to the same aspect as the original - var imageWidth = Math.Abs(posterHeight * currentImage.Width / currentImage.Height); - using var resizedBitmap = new SKBitmap(imageWidth, posterHeight); - currentImage.ScalePixels(resizedBitmap, SKFilterQuality.High); - - // draw on canvas - canvas.DrawBitmap(resizedBitmap, currentWidthPos, currentHeight); + bitmap = new SKBitmap(WallWidth, WallHeight); + using var canvas = new SKCanvas(bitmap); + canvas.Clear(SKColors.Black); - currentWidthPos += imageWidth + Spacing; + int posterHeight = WallHeight / 6; - currentImage.Dispose(); + for (int i = 0; i < Rows; i++) + { + int imageCounter = Random.Shared.Next(0, 5); + int currentWidthPos = i * 75; + int currentHeight = i * (posterHeight + Spacing); - if (imageCounter >= 4) - { - imageCounter = 0; - } - else + while (currentWidthPos < WallWidth) { - imageCounter++; + SKBitmap? currentImage; + + switch (imageCounter) + { + case 0: + case 2: + case 3: + currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, posters, posterIndex, out int newPosterIndex); + posterIndex = newPosterIndex; + break; + default: + currentImage = SkiaHelper.GetNextValidImage(_skiaEncoder, backdrops, backdropIndex, out int newBackdropIndex); + backdropIndex = newBackdropIndex; + break; + } + + if (currentImage is null) + { + throw new ArgumentException("Not enough valid pictures provided to create a splashscreen!"); + } + + using (currentImage) + { + var imageWidth = Math.Abs(posterHeight * currentImage.Width / currentImage.Height); + using var resizedBitmap = new SKBitmap(imageWidth, posterHeight); + currentImage.ScalePixels(resizedBitmap, SKFilterQuality.High); + + // draw on canvas + canvas.DrawBitmap(resizedBitmap, currentWidthPos, currentHeight); + + // resize to the same aspect as the original + currentWidthPos += imageWidth + Spacing; + } + + if (imageCounter >= 4) + { + imageCounter = 0; + } + else + { + imageCounter++; + } } } - } - return bitmap; + return bitmap; + } + catch (Exception e) + { + _logger.LogError(e, "Detected intermediary error creating splashscreen image"); + bitmap?.Dispose(); + throw; + } } /// <summary> @@ -123,25 +138,35 @@ public class SplashscreenBuilder /// <returns>The transformed image.</returns> private SKBitmap Transform3D(SKBitmap input) { - var bitmap = new SKBitmap(FinalWidth, FinalHeight); - using var canvas = new SKCanvas(bitmap); - canvas.Clear(SKColors.Black); - var matrix = new SKMatrix + SKBitmap? bitmap = null; + try { - ScaleX = 0.324108899f, - ScaleY = 0.563934922f, - SkewX = -0.244337708f, - SkewY = 0.0377609022f, - TransX = 42.0407715f, - TransY = -198.104706f, - Persp0 = -9.08959337E-05f, - Persp1 = 6.85242048E-05f, - Persp2 = 0.988209724f - }; - - canvas.SetMatrix(matrix); - canvas.DrawBitmap(input, 0, 0); - - return bitmap; + bitmap = new SKBitmap(FinalWidth, FinalHeight); + using var canvas = new SKCanvas(bitmap); + canvas.Clear(SKColors.Black); + var matrix = new SKMatrix + { + ScaleX = 0.324108899f, + ScaleY = 0.563934922f, + SkewX = -0.244337708f, + SkewY = 0.0377609022f, + TransX = 42.0407715f, + TransY = -198.104706f, + Persp0 = -9.08959337E-05f, + Persp1 = 6.85242048E-05f, + Persp2 = 0.988209724f + }; + + canvas.SetMatrix(matrix); + canvas.DrawBitmap(input, 0, 0); + + return bitmap; + } + catch (Exception e) + { + _logger.LogError(e, "Detected intermediary error creating splashscreen image transforming the image"); + bitmap?.Dispose(); + throw; + } } } |
