Allow rendering with Docnet PDF
This commit is contained in:
@@ -1,3 +1,32 @@
|
|||||||
|
magick "2026-01-29 — \$210 — WORK PERMIT.pdf" -background white -alpha background -alpha off -density 288 -resize 25% page-%03d.jpg
|
||||||
|
https://github.com/dlemstra/Magick.NET/blob/main/docs/ConvertPDF.md
|
||||||
|
https://stackoverflow.com/questions/65089839/add-an-external-pdf-page-to-pdfsharp-migradoc
|
||||||
|
https://github.com/mephraim/ghostscriptsharp
|
||||||
|
https://stackoverflow.com/a/71485279/3938401
|
||||||
|
|
||||||
|
need a PDF viewer that works with annotations
|
||||||
|
https://github.com/BobLd/PdfPig.Rendering.Skia/ works but quality is low for some reason, I don't know why. probably need a bug report or some option that is hidden.
|
||||||
|
using (var document = UglyToad.PdfPig.PdfDocument.Open(filePath, UglyToad.PdfPig.Rendering.Skia.SkiaRenderingParsingOptions.Instance))
|
||||||
|
{
|
||||||
|
|
||||||
|
document.AddSkiaPageFactory(); // Same as document.AddPageFactory<SKPicture, SkiaPageFactory>() and document.AddPageFactory<PdfPageSize, PageSizeFactory>()
|
||||||
|
|
||||||
|
for (int p = 1; p <= document.NumberOfPages; p++)
|
||||||
|
{
|
||||||
|
using var skBitmap = document.GetPageAsSKBitmap(p, 1);
|
||||||
|
using (var fs = new FileStream(Path.Combine(convertedDir, $"{fileName}_{p}PIG.jpeg"), FileMode.Create))
|
||||||
|
using (var ms = document.GetPageAsPng(p, 1, 4))
|
||||||
|
{
|
||||||
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
|
skBitmap.Encode(memoryStream, SkiaSharp.SKEncodedImageFormat.Jpeg, 100);
|
||||||
|
memoryStream.Position = 0L;
|
||||||
|
|
||||||
|
ms.WriteTo(fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
https://github.com/GowenGit/docnet -- may need to fork this and publish our own package if some OS doesn't work
|
||||||
|
|
||||||
*-add more items
|
*-add more items
|
||||||
*-save last opened folder to settings somewhere
|
*-save last opened folder to settings somewhere
|
||||||
|
|
||||||
|
|||||||
@@ -51,5 +51,7 @@
|
|||||||
<PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" />
|
<PackageReference Include="Deadpikle.AvaloniaProgressRing" Version="0.10.11-preview20251127001" />
|
||||||
<PackageReference Include="DialogHost.Avalonia" Version="0.10.4" />
|
<PackageReference Include="DialogHost.Avalonia" Version="0.10.4" />
|
||||||
<PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" />
|
<PackageReference Include="Xaml.Behaviors.Interactions.DragAndDrop.DataGrid" Version="11.3.9.5" />
|
||||||
|
<PackageReference Include="Docnet.Core" Version="2.6.0" />
|
||||||
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ namespace MayShow.Models;
|
|||||||
class Settings : ChangeNotifier
|
class Settings : ChangeNotifier
|
||||||
{
|
{
|
||||||
private string _lastUsedPath;
|
private string _lastUsedPath;
|
||||||
|
private bool _useDocnetPDFImageRendering;
|
||||||
|
|
||||||
public Settings()
|
public Settings()
|
||||||
{
|
{
|
||||||
_lastUsedPath = "";
|
_lastUsedPath = "";
|
||||||
|
_useDocnetPDFImageRendering = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonInclude]
|
[JsonInclude]
|
||||||
@@ -25,6 +27,13 @@ class Settings : ChangeNotifier
|
|||||||
set { _lastUsedPath = value; NotifyPropertyChanged(); }
|
set { _lastUsedPath = value; NotifyPropertyChanged(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonInclude]
|
||||||
|
public bool UseDocnetPFDImageRendering
|
||||||
|
{
|
||||||
|
get => _useDocnetPDFImageRendering;
|
||||||
|
set { _useDocnetPDFImageRendering = value; NotifyPropertyChanged(); }
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetSettingsFileName()
|
public static string GetSettingsFileName()
|
||||||
{
|
{
|
||||||
return "settings.json";
|
return "settings.json";
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ using MayShow.Interfaces;
|
|||||||
using MayShow.Models;
|
using MayShow.Models;
|
||||||
using MayShows.Helpers;
|
using MayShows.Helpers;
|
||||||
|
|
||||||
|
using Docnet.Core.Models;
|
||||||
|
using Docnet.Core;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
using Docnet.Core.Readers;
|
||||||
|
|
||||||
namespace MayShow.ViewModels;
|
namespace MayShow.ViewModels;
|
||||||
|
|
||||||
class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
|
class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
|
||||||
@@ -708,7 +716,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
|
|||||||
filePath = convertedOutputPath;
|
filePath = convertedOutputPath;
|
||||||
LogInfo(string.Format("Saved adjusted image to JPEG; file path is now {0}", filePath));
|
LogInfo(string.Format("Saved adjusted image to JPEG; file path is now {0}", filePath));
|
||||||
}
|
}
|
||||||
}
|
// write to PDF
|
||||||
var paragraph = section.AddParagraph();
|
var paragraph = section.AddParagraph();
|
||||||
paragraph.Format.Alignment = ParagraphAlignment.Center;
|
paragraph.Format.Alignment = ParagraphAlignment.Center;
|
||||||
var image = paragraph.AddImage(filePath);
|
var image = paragraph.AddImage(filePath);
|
||||||
@@ -721,14 +729,67 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
|
|||||||
{
|
{
|
||||||
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins...
|
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins...
|
||||||
}
|
}
|
||||||
LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath));
|
}
|
||||||
if (isPDF)
|
else
|
||||||
{
|
{
|
||||||
// add other PDF pages
|
// need to render PDF to images
|
||||||
|
if (_settings.UseDocnetPFDImageRendering)
|
||||||
|
{
|
||||||
|
// render using Docnet library (which utilizes pdfium, the chrome renderer)
|
||||||
|
string RenderPdfPageToImage(IDocReader docReader, int pgNum)
|
||||||
|
{
|
||||||
|
Console.WriteLine("rendering pg " + pgNum);
|
||||||
|
using var pageReader = docReader.GetPageReader(pgNum);
|
||||||
|
var rawBytes = pageReader.GetImage(RenderFlags.RenderAnnotations);
|
||||||
|
var width = pageReader.GetPageWidth();
|
||||||
|
var height = pageReader.GetPageHeight();
|
||||||
|
using var img = Image.LoadPixelData<Bgra32>(rawBytes, width, height);
|
||||||
|
// you are likely going to want this as well otherwise you might end up with transparent parts.
|
||||||
|
img.Mutate(x => x.BackgroundColor(SixLabors.ImageSharp.Color.White));
|
||||||
|
var pdfPageImageOutputPath = Path.Combine(convertedDir, info.Name + "-Page-"
|
||||||
|
+ (pgNum + 1).ToString().PadLeft(3, '0') + ".jpg");
|
||||||
|
img.Save(pdfPageImageOutputPath);
|
||||||
|
return pdfPageImageOutputPath;
|
||||||
|
}
|
||||||
|
// render all pages to images
|
||||||
|
using var docReader = DocLib.Instance.GetDocReader(
|
||||||
|
filePath,
|
||||||
|
new PageDimensions(1080, 1920)); // TODO: are these dims right?
|
||||||
|
// add to document
|
||||||
|
var pgCount = docReader.GetPageCount();
|
||||||
|
if (pgCount > 0)
|
||||||
|
{
|
||||||
|
var convertedPdfImagePath = RenderPdfPageToImage(docReader, 0);
|
||||||
|
imageTitlePar.AddText(string.Format(" (PDF with {0} page{1}) ",
|
||||||
|
pgCount,
|
||||||
|
pgCount == 1 ? "" : "s"));
|
||||||
|
var paragraph = section.AddParagraph();
|
||||||
|
paragraph.Format.Alignment = ParagraphAlignment.Center;
|
||||||
|
var image = paragraph.AddImage(convertedPdfImagePath);
|
||||||
|
for (var j = 1; j < pgCount; j++)
|
||||||
|
{
|
||||||
|
section.AddPageBreak();
|
||||||
|
paragraph = section.AddParagraph();
|
||||||
|
paragraph.Format.Alignment = ParagraphAlignment.Center;
|
||||||
|
convertedPdfImagePath = RenderPdfPageToImage(docReader, j);
|
||||||
|
image = paragraph.AddImage(convertedPdfImagePath);
|
||||||
|
image.LockAspectRatio = true;
|
||||||
|
image.Width = imageWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// render first page (eventually need to improve code to just do everything in a loop)
|
||||||
|
var paragraph = section.AddParagraph();
|
||||||
|
paragraph.Format.Alignment = ParagraphAlignment.Center;
|
||||||
|
var image = paragraph.AddImage(filePath);
|
||||||
|
image.LockAspectRatio = true;
|
||||||
|
image.Width = imageWidth; // can't be too wide now...not sure why...maybe due to margins...
|
||||||
|
// render other PDF pages, if any
|
||||||
// see: https://stackoverflow.com/a/65091204/3938401
|
// see: https://stackoverflow.com/a/65091204/3938401
|
||||||
var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import);
|
var pdfFileToAdd = PdfReader.Open(filePath, PdfDocumentOpenMode.Import);
|
||||||
var pgCount = pdfFileToAdd.PageCount;
|
var pgCount = pdfFileToAdd.PageCount;
|
||||||
pdfFileToAdd.Close();
|
|
||||||
imageTitlePar.AddText(string.Format(" (PDF with {0} page{1}) ",
|
imageTitlePar.AddText(string.Format(" (PDF with {0} page{1}) ",
|
||||||
pgCount,
|
pgCount,
|
||||||
pgCount == 1 ? "" : "s"));
|
pgCount == 1 ? "" : "s"));
|
||||||
@@ -742,6 +803,8 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
|
|||||||
image.Width = imageWidth;
|
image.Width = imageWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
LogInfo(string.Format("Added image: {0} ({1})", file.Title, filePath));
|
||||||
hasAddedData = true;
|
hasAddedData = true;
|
||||||
}
|
}
|
||||||
var pdfRenderer = new PdfDocumentRenderer
|
var pdfRenderer = new PdfDocumentRenderer
|
||||||
|
|||||||
Reference in New Issue
Block a user