System.drawing.common the type initializer for 'gdip' threw an exception
Asked Answered
D

7

27

This is my code to add a picture to a worksheet. I get the picture as a byte from the database. .Net Core framework version is 2.2.104. This is an API project. In my locale, the code works well. I use the ClosedXML component 0.95.4 version as below.

[HttpPost("GetTowel")]
public IActionResult GetTowel()
{
    string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    string fileName = "Towel Quotation.xlsx";
    try
    {
        using (var workbook = new XLWorkbook())
        {
            IXLWorksheet worksheet = workbook.Worksheets.Add("Towel Quotation");
            
            byte[] bytes = _fileService.Get(159).FileInBytes;
            System.IO.Stream x = new System.IO.MemoryStream(bytes);

            //the exception is throwed at this line:
            **var image = worksheet.AddPicture(x).MoveTo(worksheet.Cell("P1")).Scale(1.0);**

            using (var stream = new MemoryStream())
            {
                workbook.SaveAs(stream);
                var content = stream.ToArray();
                return File(content, contentType, fileName);
            }
        }
    }
    catch (Exception ex)
    {
        return BadRequest(ErrorResultFormatter.PrepareErrorResult("",ex.Message));
    }
}

frameworks

My Kubernetes server information is below:

System.drawing.common the type initializer for 'gdip' threw an exception
*FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /app
COPY *.csproj Nuget.Config ./ RUN dotnet restore /property:Configuration=Release
--configfile=Nuget.Config --no-cache --force
COPY . ./temp/ WORKDIR /app/temp RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ENV ASPNETCORE_URLS="http://+" ENV ASPNETCORE_Kestrel__Certificates__Default__Password="*****" WORKDIR /app COPY --from=build /app/temp/out ./ ENTRYPOINT ["dotnet", "blahblah.dll"]*

On the server-side, I get the exception as below: "system.drawing.common the type initializer for 'gdip' threw an exception"

I have searched many times on google. That way is suggested generally to add docker file:

RUN apt-get install libgdiplus

But this way also didn't solve my problem. Can anybody help me?

Thanks in advance.

Develop answered 14/4, 2021 at 12:24 Comment(3)
is this a windows or a linux container?Salmons
You may use this repo for generating simple excel files: github.com/doxa-labs/ExcelLabsMonophysite
You need libc6-dev too. Check that it is installed.Hopehopeful
M
39

I have a Dockerfile like this:

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
RUN apt-get update && apt-get install -y apt-utils libgdiplus libc6-dev
        
WORKDIR /app
EXPOSE 80
EXPOSE 443
        
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ...
    
.
.
.
    
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "...dll"]

I am running apt-get update and install command on the second line. You may run your command like this. I hope it works for you too.

Monophysite answered 14/4, 2021 at 13:6 Comment(1)
The apt-utils libgdiplus libc6-dev bits did the trick; thanks!Rheotaxis
W
24

Fix for ClosedXML 0.96.0, .NET 6, and Alpine Linux throwing the following exception when creating an Excel file:

The type initializer for 'Gdip' threw an exception

  1. Add the libgdiplus package

    Dockerfile

     FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine 
     RUN apk add libgdiplus --repository http://dl-.alpinelinux.org/alpine/edge/testing/ 
     RUN apk add ttf-freefont libssl1.1 
     ...
    
  2. Enable System.Drawing support for non-Windows platforms: (reference):

    In your project file (*.csproj), add:

     <ItemGroup>
         <RuntimeHostConfigurationOption Include="System.Drawing.EnableUnixSupport" Value="true" />
     </ItemGroup
    
Wolfort answered 20/7, 2022 at 16:45 Comment(0)
O
20

The most accepted answer did not work for me on ubuntu 20.04 and it looks like support for non-windows os's is removed for .NET 6:

System.Drawing.Common only supported on Windows

The suggested alternatives are:

To use these APIs for cross-platform apps, migrate to one of the following libraries:

ImageSharp https://github.com/SixLabors/ImageSharp

SkiaSharp https://github.com/mono/SkiaSharp

Microsoft.Maui.Graphics https://github.com/dotnet/Microsoft.Maui.Graphics

Oophorectomy answered 25/11, 2021 at 6:20 Comment(3)
From .NET 6 this is the best answer because it includes also a specific Microsoft workaround to keep working System.Drawing.Common also with .NET 6 even if it is not advisable.Hebdomadal
There are at least two forks that aim to add some kind of linux support imagesharp based and skiasharp basedGustafson
this does not help if the error come from closed-xmlHellcat
K
9

For me, the following fixed the issue (in local tests and also deployments using Ubuntu Agent in Azure):

Here is what I have in my Dockerfile:

  FROM mcr.microsoft.com/dotnet/aspnet:6.0 as base
  RUN apt-get update && apt-get install -y libgdiplus
  WORKDIR /app
  EXPOSE 80

Here is what I have added into every *.csproj file:

  <ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Drawing.EnableUnixSupport" Value="true" />
  </ItemGroup>

And I also had to install this NuGet package too: "System.Drawing.Common"

Konrad answered 6/10, 2022 at 16:50 Comment(2)
This worked for me. I did not have to add System.Drawing.Common though.Raber
Thank you for helping me. I don't even have to install the NuGet package.Strontianite
A
6

I had this problem when deploying on Linux server

try it :

sudo apt-get install -y libgdiplus

and restart server

sudo systemctl restart nginx
Australian answered 5/6, 2022 at 15:10 Comment(1)
I met this problem on macos, so solution is sudo port install libgdiplus or brew install mono-libgdiplusBruin
S
1

Try to install the libgdi NuGet package within your project. See: https://github.com/eugeneereno/libgdiplus-packaging

dotnet add package ereno.linux-x64.eugeneereno.System.Drawing

For Mac users see: https://github.com/eugeneereno/libgdiplus-packaging

Soloist answered 24/8, 2022 at 19:50 Comment(0)
C
0

Add in that code in your docker file for install the libgdi.

RUN apt-get update && apt-get install -y libgdiplus

After that add in that code in your .csproj file for enable unix support.

<ItemGroup>
        <RuntimeHostConfigurationOption Include="System.Drawing.EnableUnixSupport" Value="true" />
</ItemGroup>

And be victorious mate!

Conjecture answered 6/12, 2023 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.