jellyfin-srfPlay/Jellyfin.Plugin.SRFPlay/Utilities/PlaceholderImageGenerator.cs
Duncan Tourolle 7f71d3419c
All checks were successful
🏗️ Build Plugin / build (push) Successful in 2m49s
🧪 Test Plugin / test (push) Successful in 1m21s
🚀 Release Plugin / build-and-release (push) Successful in 2m46s
Add repo manifest
Use title cards when non provided or is livestream
2025-12-20 14:28:39 +01:00

74 lines
2.4 KiB
C#

using System.IO;
using SkiaSharp;
namespace Jellyfin.Plugin.SRFPlay.Utilities;
/// <summary>
/// Generates placeholder images for content without thumbnails.
/// </summary>
public static class PlaceholderImageGenerator
{
private const int Width = 640;
private const int Height = 360; // 16:9 aspect ratio
/// <summary>
/// Generates a placeholder image with the given text centered.
/// </summary>
/// <param name="text">The text to display (typically channel/show name).</param>
/// <returns>A memory stream containing the PNG image.</returns>
public static MemoryStream GeneratePlaceholder(string text)
{
using var surface = SKSurface.Create(new SKImageInfo(Width, Height));
var canvas = surface.Canvas;
// Dark gradient background
using var backgroundPaint = new SKPaint();
using var shader = SKShader.CreateLinearGradient(
new SKPoint(0, 0),
new SKPoint(Width, Height),
new[] { new SKColor(45, 45, 48), new SKColor(28, 28, 30) },
null,
SKShaderTileMode.Clamp);
backgroundPaint.Shader = shader;
canvas.DrawRect(0, 0, Width, Height, backgroundPaint);
// Text
using var textPaint = new SKPaint
{
Color = SKColors.White,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold)
};
// Calculate font size to fit text (max 48, min 24)
float fontSize = 48;
textPaint.TextSize = fontSize;
var textWidth = textPaint.MeasureText(text);
var maxWidth = Width * 0.85f;
if (textWidth > maxWidth)
{
fontSize = fontSize * maxWidth / textWidth;
fontSize = fontSize < 24 ? 24 : fontSize;
textPaint.TextSize = fontSize;
}
// Center text vertically
SKRect textBounds = default;
textPaint.MeasureText(text, ref textBounds);
var yPos = (Height / 2) - textBounds.MidY;
canvas.DrawText(text, Width / 2, yPos, textPaint);
// Encode to PNG
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
var stream = new MemoryStream();
data.SaveTo(stream);
stream.Position = 0;
return stream;
}
}