diff options
Diffstat (limited to 'src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs')
| -rw-r--r-- | src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs | 247 |
1 files changed, 123 insertions, 124 deletions
diff --git a/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs b/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs index 7fbae3349..990556623 100644 --- a/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs +++ b/src/Jellyfin.Drawing.Skia/SplashscreenBuilder.cs @@ -2,147 +2,146 @@ using System; using System.Collections.Generic; using SkiaSharp; -namespace Jellyfin.Drawing.Skia +namespace Jellyfin.Drawing.Skia; + +/// <summary> +/// Used to build the splashscreen. +/// </summary> +public class SplashscreenBuilder { + private const int FinalWidth = 1920; + private const int FinalHeight = 1080; + // generated collage resolution should be higher than the final resolution + private const int WallWidth = FinalWidth * 3; + private const int WallHeight = FinalHeight * 2; + private const int Rows = 6; + private const int Spacing = 20; + + private readonly SkiaEncoder _skiaEncoder; + /// <summary> - /// Used to build the splashscreen. + /// Initializes a new instance of the <see cref="SplashscreenBuilder"/> class. /// </summary> - public class SplashscreenBuilder + /// <param name="skiaEncoder">The SkiaEncoder.</param> + public SplashscreenBuilder(SkiaEncoder skiaEncoder) { - private const int FinalWidth = 1920; - private const int FinalHeight = 1080; - // generated collage resolution should be higher than the final resolution - private const int WallWidth = FinalWidth * 3; - private const int WallHeight = FinalHeight * 2; - private const int Rows = 6; - private const int Spacing = 20; - - private readonly SkiaEncoder _skiaEncoder; - - /// <summary> - /// Initializes a new instance of the <see cref="SplashscreenBuilder"/> class. - /// </summary> - /// <param name="skiaEncoder">The SkiaEncoder.</param> - public SplashscreenBuilder(SkiaEncoder skiaEncoder) - { - _skiaEncoder = skiaEncoder; - } + _skiaEncoder = skiaEncoder; + } - /// <summary> - /// Generate a splashscreen. - /// </summary> - /// <param name="posters">The poster paths.</param> - /// <param name="backdrops">The landscape paths.</param> - /// <param name="outputPath">The output path.</param> - public void GenerateSplash(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops, string outputPath) - { - using var wall = GenerateCollage(posters, backdrops); - using var transformed = Transform3D(wall); + /// <summary> + /// Generate a splashscreen. + /// </summary> + /// <param name="posters">The poster paths.</param> + /// <param name="backdrops">The landscape paths.</param> + /// <param name="outputPath">The output path.</param> + public void GenerateSplash(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops, string outputPath) + { + using var wall = GenerateCollage(posters, backdrops); + using var transformed = Transform3D(wall); - using var outputStream = new SKFileWStream(outputPath); - using var pixmap = new SKPixmap(new SKImageInfo(FinalWidth, FinalHeight), transformed.GetPixels()); - pixmap.Encode(outputStream, StripCollageBuilder.GetEncodedFormat(outputPath), 90); - } + using var outputStream = new SKFileWStream(outputPath); + using var pixmap = new SKPixmap(new SKImageInfo(FinalWidth, FinalHeight), transformed.GetPixels()); + pixmap.Encode(outputStream, StripCollageBuilder.GetEncodedFormat(outputPath), 90); + } - /// <summary> - /// Generates a collage of posters and landscape pictures. - /// </summary> - /// <param name="posters">The poster paths.</param> - /// <param name="backdrops">The landscape paths.</param> - /// <returns>The created collage as a bitmap.</returns> - private SKBitmap GenerateCollage(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) - { - var posterIndex = 0; - var backdropIndex = 0; + /// <summary> + /// Generates a collage of posters and landscape pictures. + /// </summary> + /// <param name="posters">The poster paths.</param> + /// <param name="backdrops">The landscape paths.</param> + /// <returns>The created collage as a bitmap.</returns> + private SKBitmap GenerateCollage(IReadOnlyList<string> posters, IReadOnlyList<string> backdrops) + { + var posterIndex = 0; + var backdropIndex = 0; + + var bitmap = new SKBitmap(WallWidth, WallHeight); + using var canvas = new SKCanvas(bitmap); + canvas.Clear(SKColors.Black); - var bitmap = new SKBitmap(WallWidth, WallHeight); - using var canvas = new SKCanvas(bitmap); - canvas.Clear(SKColors.Black); + int posterHeight = WallHeight / 6; - int posterHeight = WallHeight / 6; + for (int i = 0; i < Rows; i++) + { + int imageCounter = Random.Shared.Next(0, 5); + int currentWidthPos = i * 75; + int currentHeight = i * (posterHeight + Spacing); - for (int i = 0; i < Rows; i++) + while (currentWidthPos < WallWidth) { - int imageCounter = Random.Shared.Next(0, 5); - int currentWidthPos = i * 75; - int currentHeight = i * (posterHeight + Spacing); + SKBitmap? currentImage; - while (currentWidthPos < WallWidth) + switch (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!"); - } - - // 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); - - currentWidthPos += imageWidth + Spacing; - - currentImage.Dispose(); - - if (imageCounter >= 4) - { - imageCounter = 0; - } - else - { - 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; } - } - return bitmap; + 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); + + currentWidthPos += imageWidth + Spacing; + + currentImage.Dispose(); + + if (imageCounter >= 4) + { + imageCounter = 0; + } + else + { + imageCounter++; + } + } } - /// <summary> - /// Transform the collage in 3D space. - /// </summary> - /// <param name="input">The bitmap to transform.</param> - /// <returns>The transformed image.</returns> - private SKBitmap Transform3D(SKBitmap input) + return bitmap; + } + + /// <summary> + /// Transform the collage in 3D space. + /// </summary> + /// <param name="input">The bitmap to transform.</param> + /// <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 { - var 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; - } + 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; } } |
