23

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.

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
Ömer Yalvaç
  • 231
  • 1
  • 2
  • 3

6 Answers6

36

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.

fatihyildizhan
  • 8,614
  • 7
  • 64
  • 88
18

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

onemorecupofcoffee
  • 2,237
  • 1
  • 15
  • 21
  • 1
    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. – E.Benedos Dec 03 '21 at 08:28
  • There are at least two forks that aim to add some kind of linux support [imagesharp based](https://github.com/0xced/ClosedXML/tree/ImageSharp) and [skiasharp based](https://www.nuget.org/packages/DocumentPartner.ClosedXML/) – stefan.seeland Feb 21 '22 at 12:30
18

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
    
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
pateegon
  • 181
  • 1
  • 2
8

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"

KVN
  • 863
  • 1
  • 17
  • 35
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
Zaid Qassim
  • 109
  • 1
  • 5
0

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

Ton Snoei
  • 2,637
  • 22
  • 23