Generate critical source image artifacts

This commit is contained in:
2026-03-17 22:28:17 +01:00
parent 4979cf87f7
commit 2936d7146f
6 changed files with 363 additions and 2 deletions

View File

@@ -4,6 +4,8 @@ namespace RolemasterDb.ImportTool;
public sealed class PdfXmlExtractor
{
public const int XmlAlignedRenderDpi = 108;
public async Task ExtractAsync(string pdfPath, string outputPath, CancellationToken cancellationToken = default)
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
@@ -33,4 +35,83 @@ public sealed class PdfXmlExtractor
throw new InvalidOperationException($"pdftohtml failed for '{pdfPath}': {error}");
}
}
public Task RenderPagePngAsync(
string pdfPath,
int pageNumber,
string outputPath,
CancellationToken cancellationToken = default) =>
RenderPngAsync(pdfPath, pageNumber, outputPath, null, null, null, null, cancellationToken);
public Task RenderCropPngAsync(
string pdfPath,
int pageNumber,
int left,
int top,
int width,
int height,
string outputPath,
CancellationToken cancellationToken = default) =>
RenderPngAsync(pdfPath, pageNumber, outputPath, left, top, width, height, cancellationToken);
private static async Task RenderPngAsync(
string pdfPath,
int pageNumber,
string outputPath,
int? left,
int? top,
int? width,
int? height,
CancellationToken cancellationToken)
{
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
var startInfo = new ProcessStartInfo
{
FileName = "pdftoppm",
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
startInfo.ArgumentList.Add("-png");
startInfo.ArgumentList.Add("-r");
startInfo.ArgumentList.Add(XmlAlignedRenderDpi.ToString());
startInfo.ArgumentList.Add("-f");
startInfo.ArgumentList.Add(pageNumber.ToString());
startInfo.ArgumentList.Add("-l");
startInfo.ArgumentList.Add(pageNumber.ToString());
startInfo.ArgumentList.Add("-singlefile");
if (left.HasValue && top.HasValue && width.HasValue && height.HasValue)
{
startInfo.ArgumentList.Add("-x");
startInfo.ArgumentList.Add(left.Value.ToString());
startInfo.ArgumentList.Add("-y");
startInfo.ArgumentList.Add(top.Value.ToString());
startInfo.ArgumentList.Add("-W");
startInfo.ArgumentList.Add(width.Value.ToString());
startInfo.ArgumentList.Add("-H");
startInfo.ArgumentList.Add(height.Value.ToString());
}
startInfo.ArgumentList.Add(pdfPath);
startInfo.ArgumentList.Add(Path.Combine(Path.GetDirectoryName(outputPath)!, Path.GetFileNameWithoutExtension(outputPath)));
using var process = new Process { StartInfo = startInfo };
process.Start();
await process.WaitForExitAsync(cancellationToken);
if (process.ExitCode != 0)
{
var error = await process.StandardError.ReadToEndAsync(cancellationToken);
throw new InvalidOperationException($"pdftoppm failed for '{pdfPath}': {error}");
}
if (!File.Exists(outputPath))
{
throw new InvalidOperationException($"pdftoppm completed but did not create '{outputPath}'.");
}
}
}