A few days ago there was an issue raised in my QrCoder project. It was reported that the code would not run under Linux, as the following error message would occur:
Unhandled Exception: System.TypeInitializationException: The type initializer for 'System.Drawing.KnownColors' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.Drawing.GDIPlus' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'gdiplus.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) at System.Drawing.GDIPlus.GdiplusStartup(UInt64& token, GdiplusStartupInput& input, [...]
However the error message had its origin not in my QrCoder, but in the interplay of the .NET core framework with the GDI Plus library. The .NET Core Framework tries to access “gdiplus.dll” when accessing “System.Drawing.GDIPlus”, which is simply not available on Linux.
First solution approach
First, ensure that GDI+ is installed at all. This can be done with the following shell command:
sudo apt-get install libgdiplus
If libgdiplus is installed, however, another important step is missing …
Link libgdiplus for .NET Core
Because the .NET Core Framework, regardless of the operating system, is looking for the library with the suffix “.dll”, it does not find the lib on Linux, although a valid version of the libgdiplus is installed. To fix this issue we create a symbolic link to the libgdiplus.so file.
cd /usr/lib sudo ln -s libgdiplus.so gdiplus.dll
After this, the error message should disappear. Now you will be able to use the QrCoder including the .NET Core Framework under Linux.
hi
I tried your solution on the server where my api is hosted on linux env. but its not working.
I posted error on github for dotnet core repository.
https://github.com/dotnet/corefx/issues/31895#issuecomment-415222526
I tried your solution, but unfortunately its still not working on ubunto 16.4
here is my code:
public static bool CreateThumbnail(int Width, int Height, Stream filePath, string saveFilePath)
{
try
{
var byteArray = filePath;
var streamImg = Image.FromStream(byteArray);
Bitmap sourceImage = new Bitmap(streamImg);
using (Bitmap objBitmap = new Bitmap(Width, Height))
{
objBitmap.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
using (Graphics objGraphics = Graphics.FromImage(objBitmap))
{
// Set the graphic format for better result cropping
objGraphics.SmoothingMode = SmoothingMode.HighQuality;
objGraphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
objGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
objGraphics.CompositingQuality = CompositingQuality.HighQuality;
objGraphics.DrawImage(sourceImage, 0, 0, Width, Height);
// Save the file path, note we use png format to support png file
objBitmap.Save(saveFilePath);
}
}
}
catch (Exception ex)
{
LogHelper.Log(“Create Thumbnail: ERROR:” + ex.Message + “\n” + ex.StackTrace);
return false;
}
return true;
}
and here is the error:
ERROR:The type initializer for ‘Gdip’ threw an exception.
at System.Drawing.SafeNativeMethods.Gdip.GdipLoadImageFromDelegate_linux(StreamGetHeaderDelegate getHeader, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, StreamSeekDelegate doSeek, StreamCloseDelegate close, StreamSizeDelegate size, IntPtr& image)
at System.Drawing.Image.InitFromStream(Stream stream)
at System.Drawing.Image.LoadFromStream(Stream stream, Boolean keepAlive)
Hi, I’m noob with docker,
I’d like to know how to run this commands in my docker file?
I tried doing this, but nothing change:
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
RUN apt-get update
RUN apt-get install -y libgdiplus
RUN cd /usr/lib
RUN sudo ln -s libgdiplus.so gdiplus.dll
WORKDIR /src
COPY *.sln ./
COPY NuGet.config ./
COPY Core.MyApp.Api/Core.MyApp.Api.csproj Core.MyApp.Api/
RUN dotnet restore Core.MyApp.Api/Core.MyApp.Api.csproj
COPY . .
WORKDIR /src/Core.MyApp.Api
RUN dotnet build Core.MyApp.Api.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish Core.MyApp.Api.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY –from=publish /app .
ENTRYPOINT [“dotnet”, “Core.MyApp.dll”]
Thank’s, I did what you said, but I have an issue regarding the color. The QrCode generated with QrCoder is weird under Linux (color not consistent and changes randomly).
Code:
var myLogo = new Bitmap(“./Assets/myLogo.png”);
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(id.ToString(), QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(6, ArgbToColor(“#FF3F729B”), ArgbToColor(“#FFFFFFFF”), myLogo, 17, 8, true);
// Convert Bitmap to Png
MemoryStream stream = new MemoryStream();
qrCodeImage.Save(stream, ImageFormat.Png);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
return File(stream, “image/png”);
Hi Nordes,
do the “changing colors” also occur if you use a color from the Color-class? (E.g. Color.Green instead of ArgbToColor(“#FF3F729B”) )
Do you use the newest version of QRCoder? (Currently it is 1.3.2)
Kind regards,
Raffael
thanks this helped me lot.