Free Support Forum - groupdocs.com

Failed to convert PDF to PNG in DotNet core 3.0 Windows Docker container

Hi,
We are getting the following error from GroupDocs library when converting a PDF to PNG. We are using AspDotNet core 3.0 in a Windows 2016 Docker container (mcr.microsoft.com/dotnet/core/aspnet:3.0-nanoserver-sac2016)

Exception -

GroupDocs.Viewer.Exceptions.GroupDocsViewerException: The type initializer for ‘Gdip’ threw an exception.
at . ​(Int32 , IPageStreamFactory )
at .(Int32[] , , PngViewOptions , IPageStreamFactory )
at . ​(Func2 , ViewOptions , Int32[] ) at .(Func2 , Int32[] , PngViewOptions )
at . ​(Func`2 , ViewOptions , Int32[] )
at GroupDocs.Viewer.Viewer.View(ViewOptions options, Int32[] pageNumbers)

This is a show-stopper for us. Any ideas to resolve / work around this?

I should mention that the same code works well when running outside a Docker container. We have pretty much copied the conversion code from the examples given in your website.

1 Like

@devam

Do you face this issue in case of a particular PDF? Or it happens for every other PDF file?
Can you please specify the GroupDocs.Viewer API version that you are evaluating (e.g. 20.1, 20.9)?

Are you working with this code? We’ll appreciate if you share your actual code (with code changes, if there are any).

@atirtahir3 Thanks for responding to the query. Here are my answers -

Do you face this issue in case of a particular PDF? Or it happens for every other PDF file?

It is failing for every file. Our use case is to convert all file types to PNG only.
This morning I tried converting some XML and JS files to PNG and the conversions failed with the following exception -

System.TypeInitializationException: The type initializer for '  ' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an 
exception.
 ---> System.DllNotFoundException: Unable to load DLL 'libSkiaSharp' or one of its dependencies: 
The specified module could not be found. (0x8007007E)
at SkiaSharp.SkiaApi.sk_colortype_get_default_8888()
at SkiaSharp.SKImageInfo..cctor()
--- End of inner exception stack trace ---
at SkiaSharp.SKBitmap..ctor(Int32 width, Int32 height, Boolean isOpaque)
at   ..cctor()
--- End of inner exception stack trace ---
at   ..ctor(Int32 , Int32 , Single , Single ,     )
at  ​ . ()
at  ​ . (Stream )
at  ​ .(   , SizeF , Stream , ImageSaveOptions , IWarningCallback ,    )
at  ​ . (Stream )
at  ​ . ​   (    )
at    .     (    )
at Aspose.Words.Document.  (    )
at Aspose.Words.Document.​(Stream , String , SaveOptions )
at Aspose.Words.Document.Save(Stream stream, SaveOptions saveOptions)
at   .(Stream ,    )
at   .(Stream ,    )
at   .()
at   .()
at   .     ​()
at GroupDocs.Viewer.Viewer.(ViewInfoOptions )
at GroupDocs.Viewer.Viewer..()
at   .[TEntry](ICache , String , Func`1 )
at GroupDocs.Viewer.Viewer.GetViewInfo(ViewInfoOptions options)

Can you please specify the GroupDocs.Viewer API version that you are evaluating (e.g. 20.1, 20.9)?

We have installed version 20.8.0 via Nuget package manager.

Example code -

We have used the ThreadSafeFileCache from this example code, and the other bits from this example in GitHub. You can ignore the MinimumPagesToConvert bit as that is specific logic to our application.

            string outputDir = Path.Combine(Utility.GroupDocsOutputPath, data.DocumentId);
            string cacheDir = Path.Combine(outputDir, "cache");
            IKeyLockerStore keyLockerStore = new ConcurrentDictionaryKeyLockerStore(KeyLockerMap, cacheDir);
            ICache threadSafeCache = new ThreadSafeFileCache(new FileCache(cacheDir), keyLockerStore);
            var settings = new ViewerSettings(threadSafeCache);

            // Convert the file to PNG
            var retVal = new Dictionary<string, string>();
            string pageFilePathFormat = Path.Combine(outputDir, "page{0}.png");
            using (var viewer = new Viewer(filePath, settings))
            {
                ViewInfo vi = viewer.GetViewInfo(ViewInfoOptions.ForPngView(false));
                var options = new PngViewOptions(pageFilePathFormat);
                if (!string.IsNullOrEmpty(data.Watermark))
                    options.Watermark = new Watermark(data.Watermark);

                // MinimumPagesToConvert or entire document whichever is smaller
                viewer.View(
                    options, 
                    Enumerable.Range(1, vi.Pages.Count < MinimumPagesToConvert ? 
                        vi.Pages.Count : MinimumPagesToConvert).ToArray());

                retVal["TotalPages"] = vi.Pages.Count.ToString();
            }

            return Ok(retVal);

@devam

We are investigating this issue with ticket ID VIEWERNET-2767. As there’s any update, you’ll be notified.

@devam

There’s an update on VIEWERNET-2767.
Unfortunately, Nano Server is not supported due to Nano Server limitations. What are the workarounds?

  • Windows Server Core - We’ve found that PDF to PNG rendering is not working when running in Windows Server Core, this issue has been logged. While the image has a significantly larger on-disk footprint comparing to Nano Server it can be used to build and run .NET Framework applications. Please check the docker_viewer_win.zip (708.4 KB) that is targeting .NET Framework and running in Windows Server Core.
  • Linux - Here we still can reproduce issues with rendering PDF files but the image size is much smaller comparing to Windows Server Core. We’re actively improving Linux support. So, we would recommend using Linux containers instead of Windows. The attached .NET Core 3.1 docker_viewer_linux.zip (11.1 KB) contains Dockerfile with all required dependencies installed. We’re using the same Dockerfile to run our tests.

@atirtahir3 - thanks once again for your prompt and detailed response. We are however a Windows shop and would therefore need to head towards server core base image. Can we can use your DLL in a self contained aspnet dotnet core web api application as opposed to using .Net Framework?

@devam

We’re looking into this use-case, you’ll be notified about the outcomes.

@devam

Sure, the GroupDocs.Viewer can be used with self-contained .NET Core apps when running in Windows Server Core Docker Container. Please check the sample .NET Core application web_api.zip (17.2 KB) as a demonstration.

Here are the steps to run the app:

  • Unpack the archive
  • Create artifacts by running dotnet publish -r win10-x64 -o artifacts - the self-contained application will be created in the artifacts folder.
  • Build the container image by running docker build -t groupdocs-viewer:docker_viewer_win_core . . Note instruction EXPOSE 5000 and environment variable ENV ASPNETCORE_URLS=http://*:5000 in the Dockerfile.
  • Run the container image docker run -it --rm groupdocs-viewer:docker_viewer_win_core
  • Inspect container IP docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' <container>
  • Test Viewer endpoint <IP>:5000/viewer/1 - the first page of the DOC contained in the web_api.zip (17.2 KB) archive in PNG format will be returned in the response.

Let us know if it’s helpful.