sungaila / PDFtoImage

A .NET library to render PDF files into images.
https://www.sungaila.de/PDFtoImage/
MIT License
174 stars 18 forks source link

Blazor WebAssembly: System.DllNotFoundException: libSkiaSharp #95

Closed tschramme86 closed 1 week ago

tschramme86 commented 1 week ago

PDFtoImage version

4.1.0

OS

Windows

OS version

Windows 11 24H2

Architecture

x64

Framework

.NET (Core)

App framework

Blazor WebAssembly

Detailed bug report

It is mentioned that this Library works also in Blazor WebAssembly projects. I tried but always get this exception when calling PDFToImage.Conversion.SavePng method: System.DllNotFoundException: libSkiaSharp

Steps to reproduce:

var pdfFile = "[base64 PDF file data - removed for this example]";
using(var mem = new MemoryStream())
{
    PDFtoImage.Conversion.SavePng(mem, pdfFile);
    var png = mem.ToArray();
}

Project file for reference:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.8" PrivateAssets="all" />
    <PackageReference Include="PDFtoImage" Version="4.1.0" />
  </ItemGroup>
</Project>

Result When running the project and clicking the button on the page to call the above code, the SavePng function throws the following exception:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
 ---> System.DllNotFoundException: libSkiaSharp
   at SkiaSharp.SKImageInfo..cctor()
   --- End of inner exception stack trace ---
   at SkiaSharp.SKBitmap..ctor(Int32 width, Int32 height, SKColorType colorType, SKAlphaType alphaType)
   at PDFtoImage.Internals.PdfDocument.RenderSubset(PdfFile file, Int32 page, Single width, Single height, PdfRotation rotate, FPDF flags, Boolean renderFormFill, SKColor backgroundColor, Nullable`1 bounds, Single originalWidth, Single originalHeight, CancellationToken cancellationToken)
   at PDFtoImage.Internals.PdfDocument.Render(Int32 page, Nullable`1 requestedWidth, Nullable`1 requestedHeight, Single dpiX, Single dpiY, PdfRotation rotate, FPDF flags, Boolean renderFormFill, SKColor backgroundColor, Nullable`1 bounds, Boolean useTiling, Boolean withAspectRatio, Boolean dpiRelativeToBounds, CancellationToken cancellationToken)
   at PDFtoImage.Conversion.RenderImpl(PdfDocument pdfDocument, Int32 page, FPDF renderFlags, RenderOptions options)
   at PDFtoImage.Conversion.ToImagesImpl(PdfDocument pdfDocument, RenderOptions options, IEnumerable`1 pages)+MoveNext()
   at PDFtoImage.Conversion.ToImagesImpl(Stream pdfStream, Boolean leaveOpen, String password, RenderOptions options, IEnumerable`1 pages)+MoveNext()
   at System.Linq.Enumerable.TryGetFirst[SKBitmap](IEnumerable`1 source, Boolean& found)
   at System.Linq.Enumerable.First[SKBitmap](IEnumerable`1 source)
   at PDFtoImage.Conversion.ToImage(Stream pdfStream, Boolean leaveOpen, String password, Int32 page, RenderOptions options)
   at PDFtoImage.Conversion.ToImage(Byte[] pdfAsByteArray, String password, Int32 page, RenderOptions options)
   at PDFtoImage.Conversion.ToImage(String pdfAsBase64String, String password, Int32 page, RenderOptions options)
   at PDFtoImage.Conversion.SaveImpl(Stream imageStream, SKEncodedImageFormat format, String pdfAsBase64String, String password, Int32 page, RenderOptions options)
   at PDFtoImage.Conversion.SavePng(Stream imageStream, String pdfAsBase64String, String password, Int32 page, RenderOptions options)
   at BlazorPdfTest.Pages.Counter.IncrementCount() in D:\Source\BlazorPdfTest\Pages\Counter.razor:line 20
   at Microsoft.AspNetCore.Components.EventCallbackWorkItem.InvokeAsync[Object](MulticastDelegate delegate, Object arg)
   at Microsoft.AspNetCore.Components.EventCallbackWorkItem.InvokeAsync(Object arg)
   at Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, Object arg)
   at Microsoft.AspNetCore.Components.EventCallback.InvokeAsync(Object arg)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.DispatchEventAsync(UInt64 eventHandlerId, EventFieldInfo fieldInfo, EventArgs eventArgs, Boolean waitForQuiescence)
sungaila commented 1 week ago

Hi @tschramme86,

thanks for opening this issue! You'll have to add these lines to your project file:

<ItemGroup>
    <NativeFileReference Include="$(SkiaSharpStaticLibraryPath)\3.1.12\simd\libSkiaSharp.a" />
</ItemGroup>

I'll fix this in a future release of PDFtoImage so this will be set by a props file automatically.

tschramme86 commented 1 week ago

Thanks for the very quick response @sungaila, really appreciate! With the additional lines in the project file it works :)

sungaila commented 1 week ago

@tschramme86 PDFtoImage 4.1.1 has been released, where this problem has been fixed. You can remove the <NativeFileReference /> once you update to this version.

Please reopen this issue if it isn't working as expected.