Add image generation

This commit is contained in:
2025-07-15 02:42:16 +02:00
parent 9cfbdc21d0
commit 480a38baac
17 changed files with 635 additions and 12 deletions

View File

@@ -0,0 +1,75 @@
using System.Reflection;
using HomeApi.Models;
using HomeApi.Models.Configuration;
using MediatR;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.Extensions.Options;
using PuppeteerSharp;
using RazorLight;
namespace HomeApi.Handlers;
public static class ImageGeneration
{
public record Command : IRequest<Stream>;
public class Handler : IRequestHandler<Command, Stream>
{
private readonly ILogger<Handler> _logger;
private readonly IWebHostEnvironment _env;
private readonly IMediator _mediator;
public Handler(
IOptions<ApiConfiguration> apiConfiguration,
ILogger<Handler> logger, IWebHostEnvironment env, IMediator mediator)
{
_logger = logger;
_env = env;
_mediator = mediator;
}
public async Task<Stream> Handle(Command request, CancellationToken cancellationToken)
{
var weather = await _mediator.Send(new Weather.Command(), cancellationToken);
var departureBoard = await _mediator.Send(new DepartureBoard.Command(), cancellationToken);
var model = new Image
{
Weather = weather,
TimeTable = departureBoard
};
if(weather is null)
throw new Exception("Weather data not found");
var engine = new RazorLightEngineBuilder().SetOperatingAssembly(Assembly.GetExecutingAssembly())
.UseEmbeddedResourcesProject(typeof(ImageGeneration)).UseMemoryCachingProvider().Build();
var path = Path.Combine(_env.WebRootPath, "index.cshtml");
var template = await File.ReadAllTextAsync(path);
var result = await engine.CompileRenderStringAsync("templateKey", template, model);
return await CreateImage(result);
}
private static async Task<Stream> CreateImage(string htmlContent)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
Args = ["--disable-gpu"]
});
var page = await browser.NewPageAsync();
await page.SetViewportAsync(new ViewPortOptions
{
Width = 800,
Height = 480
});
await page.SetContentAsync(htmlContent, new NavigationOptions { WaitUntil = new[] { WaitUntilNavigation.Networkidle0 } });
var stream = await page.ScreenshotStreamAsync(new ScreenshotOptions { Type = ScreenshotType.Png });
return stream;
}
}
}