Files
PosterMaker/PosterMaker.Core/Services/SeriesPosterMakerService.cs
T
Jānis Kacēns 3889e684b4 Initial commit
2024-04-10 12:21:36 +03:00

215 lines
8.8 KiB
C#

using ImageMagick;
using PosterMaker.Interfaces.Services;
using PosterMaker.Models;
using PosterMaker.Models.Enums;
namespace PosterMaker.Services;
public class SeriesPosterMakerService : ISeriesPosterMakerService
{
private static readonly string RefDir = Path.Combine("Resources", "Series");
private static readonly string RefDirectory = Path.Combine(Directory.GetCurrentDirectory(), RefDir);
private static readonly string Font = Path.Combine(RefDirectory, "Arial Bold.ttf");
private static readonly string SeasonFont = Path.Combine(RefDirectory, "Proxima Nova Semibold.ttf");
private static readonly string Frame = Path.Combine(RefDirectory, "frame.png");
private static readonly string Gradient = Path.Combine(RefDirectory, "gradient.png");
private const string FontColor = "white";
private const float FontSize = 1.0F;
private readonly IMovieLogoService _movieLogoService;
public SeriesPosterMakerService(IMovieLogoService movieLogoService)
{
_movieLogoService = movieLogoService;
}
public byte[] CreatePoster(string file, ImageProperties imageProperties)
{
using var image = new MagickImage(file);
var resizeGeometry = new MagickGeometry(1892, 2892)
{
FillArea = true
};
image.Resize(resizeGeometry);
image.Extent(2000, 3000, Gravity.Center);
ApplyGradient(image);
using var frame = new MagickImage(Frame);
frame.BackgroundColor = new MagickColor("transparent");
image.Composite(frame, Gravity.Center, CompositeOperator.Over);
AddStudioLogo(image, imageProperties.Logo, imageProperties.LogoOption);
AddNetworkLogo(image, imageProperties.NetworkLogo, imageProperties.LogoOption);
AddTitle(image, imageProperties);
return image.ToByteArray();
}
private static void ApplyGradient(MagickImage image)
{
using var gradient = new MagickImage(Gradient);
image.Composite(gradient, Gravity.Center, CompositeOperator.Multiply);
}
private void AddStudioLogo(MagickImage image, MovieLogoEnum? logo, LogoOptionEnum? logoOptionEnum)
{
if (logo == null) return;
var logoFile = _movieLogoService.GetMovieLogo(logo);
var gravity = _movieLogoService.GetLogoGravity(logo);
var readSettings = new MagickReadSettings
{
TextGravity = Gravity.Center,
BackgroundColor = MagickColors.Transparent
};
using var logoImage = new MagickImage(logoFile, readSettings);
logoImage.Resize(new MagickGeometry(500, 250));
switch (logoOptionEnum)
{
case LogoOptionEnum.White:
logoImage.Colorize(MagickColors.White, new Percentage(100));
break;
case LogoOptionEnum.Black:
logoImage.Colorize(MagickColors.Black, new Percentage(100));
break;
}
var offset = gravity == Gravity.Northwest ? 100 : 0;
image.Composite(logoImage, gravity, offset, 100, CompositeOperator.Atop);
}
private void AddNetworkLogo(MagickImage image, NetworkLogoEnum? logo, LogoOptionEnum? logoOptionEnum)
{
if (logo == null) return;
var logoFile = _movieLogoService.GetNetworkLogo(logo);
var readSettings = new MagickReadSettings
{
TextGravity = Gravity.Center,
BackgroundColor = MagickColors.Transparent
};
using var logoImage = new MagickImage(logoFile, readSettings);
var networkLogoHeight = _movieLogoService.GetNetworkLogoHeight(logo);
logoImage.Resize(new MagickGeometry(networkLogoHeight * 2, networkLogoHeight));
switch (logoOptionEnum)
{
case LogoOptionEnum.White:
logoImage.Colorize(MagickColors.White, new Percentage(100));
break;
case LogoOptionEnum.Black:
logoImage.Colorize(MagickColors.Black, new Percentage(100));
break;
}
var shadow = new MagickImage(logoImage);
shadow.Shadow(2, 2,3, new Percentage(80));
switch (logoOptionEnum)
{
case LogoOptionEnum.White:
shadow.Colorize(MagickColors.Black, new Percentage(100));
break;
case LogoOptionEnum.Black:
shadow.Colorize(MagickColors.White, new Percentage(100));
break;
}
image.Composite(shadow, Gravity.Northwest, 100, 100, CompositeOperator.Atop);
image.Composite(logoImage, Gravity.Northwest, 100, 100, CompositeOperator.Atop);
}
private void AddTitle(MagickImage image, ImageProperties properties)
{
if (string.IsNullOrEmpty(properties.TopSubtitle) && string.IsNullOrEmpty(properties.Title) &&
string.IsNullOrEmpty(properties.Subtitle) && string.IsNullOrEmpty(properties.Season))
return;
var readSettings = new MagickReadSettings
{
BackgroundColor = MagickColors.Transparent,
FillColor = new MagickColor(FontColor),
Font = Font,
Debug = true
};
var labelImages = new MagickImageCollection();
if (!string.IsNullOrEmpty(properties.TopSubtitle))
{
readSettings.FontPointsize = 95 * FontSize;
readSettings.TextGravity = Gravity.Center;
labelImages.Add(new MagickImage($"label:{properties.TopSubtitle.ToUpper()}", readSettings));
}
if (!string.IsNullOrEmpty(properties.Title))
{
readSettings.FontPointsize = 190 * FontSize;
readSettings.TextKerning = 0.7;
readSettings.TextInterlineSpacing = -44.5;
readSettings.TextInterwordSpacing = 55;
readSettings.TextGravity = Gravity.Center;
labelImages.Add(new MagickImage($"label:{properties.Title.ToUpper()}", readSettings));
}
if (!string.IsNullOrEmpty(properties.Title2))
{
readSettings.FontPointsize = 190 * FontSize;
readSettings.TextKerning = 0.7;
readSettings.TextInterlineSpacing = -44.5;
readSettings.TextInterwordSpacing = 55;
readSettings.TextGravity = Gravity.Center;
labelImages.Add(new MagickImage($"label:{properties.Title2.ToUpper()}", readSettings));
}
if (!string.IsNullOrEmpty(properties.Subtitle))
{
readSettings.FontPointsize = 95 * FontSize;
readSettings.TextInterwordSpacing = 18;
readSettings.TextKerning = 0.5;
readSettings.TextGravity = Gravity.Center;
labelImages.Add(new MagickImage($"label:{properties.Subtitle.ToUpper()}", readSettings));
}
using var labels = labelImages.SmushVertical(30);
var seasonImages = new MagickImageCollection();
var image2 = new MagickImage();
if (!string.IsNullOrEmpty(properties.Season) && ((properties.LimitedSeries != null && properties.LimitedSeries != true) || properties.LimitedSeries == null))
{
seasonImages.Add(labels);
readSettings.TextInterlineSpacing = 150;
readSettings.FontPointsize = 66 * FontSize;
readSettings.TextGravity = Gravity.Center;
readSettings.TextKerning = 50;
readSettings.TextInterwordSpacing = 20;
readSettings.Font = SeasonFont;
var seasonImage = new MagickImage($"label:SEASON {properties.Season.ToUpper()}", readSettings);
seasonImages.Add(seasonImage);
var offset = string.IsNullOrEmpty(properties.Subtitle) ? 150 : 75;
using var imageWithSeason = seasonImages.SmushVertical(offset);
image2 = new MagickImage(imageWithSeason);
}
if (properties.LimitedSeries == true)
{
seasonImages.Add(labels);
readSettings.TextInterlineSpacing = 150;
readSettings.FontPointsize = 66 * FontSize;
readSettings.TextGravity = Gravity.Center;
readSettings.TextKerning = 50;
readSettings.TextInterwordSpacing = 20;
readSettings.Font = SeasonFont;
var seasonImage = new MagickImage($"label:LIMITED SERIES", readSettings);
seasonImages.Add(seasonImage);
using var imageWithSeason = seasonImages.SmushVertical(150);
image2 = new MagickImage(imageWithSeason);
}
var titleHeight = !string.IsNullOrEmpty(properties.Season) || properties.LimitedSeries == true ? 85 : 262;
if (!string.IsNullOrEmpty(properties.Subtitle) && properties.LimitedSeries is not true && string.IsNullOrWhiteSpace(properties.Season))
{
titleHeight = 200;
}
image.Composite(string.IsNullOrEmpty(properties.Season) && properties.LimitedSeries != true ? labels : image2, Gravity.South, 0, titleHeight, CompositeOperator.Atop);
}
}