154 lines
5.9 KiB
C#
154 lines
5.9 KiB
C#
using ImageMagick;
|
|
using PosterMaker.Interfaces.Services;
|
|
using PosterMaker.Models;
|
|
using PosterMaker.Models.Enums;
|
|
|
|
namespace PosterMaker.Services;
|
|
|
|
public class MoviePosterMakerService : IMoviePosterMakerService
|
|
{
|
|
private static readonly string RefDir = Path.Combine("Resources", "Movies");
|
|
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 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 const string IndexFontColor = "rgb(154,154,154)";
|
|
|
|
private readonly IMovieLogoService _movieLogoService;
|
|
|
|
public MoviePosterMakerService(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);
|
|
|
|
AddLogo(image, imageProperties.Logo, imageProperties.LogoOption);
|
|
AddIndex(image, imageProperties.Index);
|
|
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 static void AddIndex(MagickImage image, string? input)
|
|
{
|
|
if (string.IsNullOrEmpty(input)) return;
|
|
var readSettings = new MagickReadSettings
|
|
{
|
|
Font = Font,
|
|
FillColor = new MagickColor(IndexFontColor),
|
|
FontPointsize = 598,
|
|
TextGravity = Gravity.Center,
|
|
BackgroundColor = MagickColors.Transparent,
|
|
};
|
|
var index = new MagickImage($"label:{(input)}", readSettings);
|
|
image.Composite(index, Gravity.South, 0, 50, CompositeOperator.Atop);
|
|
}
|
|
|
|
private void AddLogo(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(_movieLogoService.GetLogoGeometry(logo));
|
|
|
|
if (logoOptionEnum == LogoOptionEnum.White)
|
|
{
|
|
logoImage.Colorize(MagickColors.White, new Percentage(100));
|
|
}
|
|
if (logoOptionEnum == LogoOptionEnum.Black)
|
|
{
|
|
logoImage.Colorize(MagickColors.Black, new Percentage(100));
|
|
}
|
|
var shadow = new MagickImage(logoImage);
|
|
shadow.Shadow(3, 3,3, new Percentage(80));
|
|
var offset = gravity == Gravity.Northwest ? 100 : 0;
|
|
image.Composite(shadow, gravity, offset, 100, CompositeOperator.Atop);
|
|
|
|
image.Composite(logoImage, gravity, offset, 100, CompositeOperator.Atop);
|
|
}
|
|
|
|
private void AddTitle(MagickImage image, ImageProperties properties)
|
|
{
|
|
if (string.IsNullOrEmpty(properties.TopSubtitle) && string.IsNullOrEmpty(properties.Title) && string.IsNullOrEmpty(properties.Subtitle))
|
|
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 titleHeight = !string.IsNullOrEmpty(properties.Subtitle) ? 182 : 262;
|
|
image.Composite(labels, Gravity.South, 0, titleHeight, CompositeOperator.Atop);
|
|
}
|
|
} |