Using System.Drawing package from multiple machines (multiple OS) - c#

We are building a .Net Core 2.0 C# web app that uses System.Drawing package.
I am writing code on Mac, but it will be also developed on the Windows machine, and deployed into Linux server.
To use System.Drawing on OSX I had to add runtime.osx.10.10-x64.CoreCompat.System.Drawing Nuget package to my project dependencies.
But that code now doesn't work on the Window machine.
We get the System.AccessViolationException when trying to use DrawString method of Graphics (part of System.Drawing) object.
So, my question is what is common way to solve this?
Is it even possible to use System.Drawing classes in this multi-os setup?

The same System.Drawing code should work on Linux, Windows and macOS without any changes. You're correct that you need to either manually install libgdiplus (e.g. via brew install mono-libgdiplus) or reference runtime.osx.10.10-x64.CoreCompat.System.Drawing for System.Drawing to work on a Mac.
System.Drawing will work on Windows without any external dependencies.
If you're still using CoreCompat.System.Drawing (which I maintain), I'd recommend you migrate to System.Drawing.Common instead - this the is Microsoft implementation of System.Drawing for .NET Core.
If the issue then still reproduces on Windows, your best bet would be copy a should piece of code which can be used to reproduce your issue, so I can have a look at it.

Related

How can I deploy .NET Framework application on Mac and Windows both? How to Build Cross-Platform(windows and MacOS) .NET Core?

I have Windows version of .NET Framework desktop application. Now I want to make version available for MacOS as well.
Is there any solution available using C#?
Will .NET Core work for both Windows and MacOs?
I have already build application using WinForms C#. I have created exe for window.. Similarly I want to run application on MacOS as well
You can try Mono then. It has (a rather limited) WinForms support. But if you never tested it on any other platforms yet, then be prepared for some issues. Among others:
You will not able to use any WinAPI directly (ie. extern methods to Win32 dlls)
You might expect some behavioral differences. Some of them affect only particular distributions.
Many of these can be handled by special handlings in you code, though. But it means you will need some IsWindowsdistinction here and there, just like in this project of mine.
And do not forget to install libgdiplus, which makes possible to use System.Drawing on non-Windows platforms, as WinForms is built on GDI+.

I am using .NET Core with C# on Linux, and library *System.Drawing* is missing

Error message
Program.cs(1,14): error CS0234: The type or namespace name 'Drawing'
does not exist in the namespace 'System' (are you missing an assembly
reference?
Is it possible to fix that? Or I am not meant to be using this library, if I am developing on Linux with C#?
2021:
Quote from System.Drawing.Common only supported on Windows, Recommended action:
To use these APIs for cross-platform apps, migrate to one of the following libraries:
ImageSharp
SkiaSharp
Microsoft.Maui.Graphics
You are able to use System.Drawing for the short term but be aware there is no support.
Alternatively, you can enable support for non-Windows platforms by setting the System.Drawing.EnableUnixSupport runtime configuration switch to true in the runtimeconfig.json file:
This configuration switch was added to give cross-platform apps that depend heavily on this package time to migrate to more modern libraries. However, non-Windows bugs will not be fixed. In addition, we may completely remove support for non-Windows platforms in a future release, even if you enable it using the runtime configuration switch.
To be able to use System.Drawing on Linux machines, you might also need to install libgdiplus as mentioned by #saman-azadi and #alex-from-jitbit.
2017:
The System.Drawing namespace is at the moment not part of corefx as it relies on the GDI+ features from Windows.
But there are plans to support it in the future.
But there are multiple alternatives:
CoreCompat.System.Drawing
CoreCompat.System.Drawing is a .NET Core port of the Mono implementation of System.Drawing. Like System.Drawing in .NET Framework and in Mono, CoreCompat.System.Drawing also relies on GDI+ on Windows. Caution is therefore advised, for the same reasons.
ImageSharp
ImageSharp is a brand new, pure managed code, and cross-platform image processing library. Its performance is not as good as that of libraries relying on native OS-specific dependencies, but it remains very reasonable. Its only dependency is .NET itself, which makes it extremely portable: there is no additional package to install, just reference ImageSharp itself, and you’re done.
Magick.NET
Magick.NET is the .NET wrapper for the popular ImageMagick library. ImageMagick is an open-source, cross-platform library that focuses on image quality, and on offering a very wide choice of supported image formats. It also has the same support for EXIF as ImageSharp.
(The .NET Core build of Magick.NET currently only supports Windows.)
SkiaSharp
SkiaSharp is the .NET wrapper for Google’s Skia cross-platform 2D graphics library, that is maintained by the Xamarin team. SkiaSharp is now compatible with .NET Core, and is extremely fast.
FreeImage-dotnet-core
This library is to the native FreeImage library what Magick.NET is to ImageMagick: a .NET Core wrapper. It offers a nice choice of image formats, good performance, and good visual quality.
Here are some good examples and performance analyses of the libraries mentioned above.
Run the following command on the command line
sudo apt-get install libgdiplus
or
sudo yum install -y libgdiplus-2.10-9.el7.x86_64
Microsoft has released System.Drawing.Common since which works on Linux too.
UPDATE: They decided to make it "Windows only" in .NET 6. The package will show compile warnings, since it relies on libgdiplus which might not be present on some Linux distribution. See System.Drawing.Common only supported on Windows.
We switched to ImageSharp since it's the only image processing library that is pure managed code and has zero unmanaged dependencies (unlike SkiaSharp or MagickNET).
You can use the Aspose.Drawing library – a drop-in replacement for System.Drawing that is fully managed and cross-platform. (I'm one of the developers.)
For those trying to use System.Drawing on Linux:
libgdiplus causes a serious memory leak on Linux (I tried it on Ubuntu 20.04 (Focal Fossa)) and should not be used (found here).
ImageSharp works hard with native code (passing memory pointers) and OpenCvSharp4 became my final choice.

using System.Drawing.Imaging; Imaging does not exist in the System.Drawing

I am attempting to pull metadata from photos in a .Net Core App by using this library:
https://www.codeproject.com/Articles/27242/ExifTagCollection-An-EXIF-metadata-extraction-libr
However while implementing the ExifTagCollection class I am getting the Error listed in the title.
I have successfully referenced System.Drawing but it is not recognizing its drawing extension. Any help would be great. Also open to suggestions for other libraries to accomplish my goal. Thx
If you're looking for System.Drawing-related functionality on .NET Core, you should be able to use System.Drawing.Common.
It provides the System.Drawing API on .NET Core and works on Windows, Linux and macOS.
If you're on Linux and macOS, you'll need to install libgdiplus for this to work. To install libgdiplus on macOS, run brew install mono-libgdiplus; on Linux you should be able to install the libgdiplus package using your package manager. This deployment will hopefully get easier in the future.
It's currently in preview on NuGet as the System.Drawing.Common package.
Long term, you may want to consider migrating to other libraries such as ImageSharp.
If you take a look at the site of microsoft you will see:
"Classes within the System.Drawing.Imaging namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions."
You are creating a web application with ASP.net so this class isn't supported for your project
As #TimonPost says, you cannot use that namespace from ASP.NET, because it relies on there being an interactive session (which is why it also won't work from a Windows Service).
If you just want an easy way to access metadata from images that works in ASP.NET Core, check out my MetadataExtractor library.
https://github.com/drewnoakes/metadata-extractor-dotnet

Monogame UWP - Including a DLL library causes error

I'm creating a Monogame UWP Project and whenever I make a call to an included very basic compiled DLL .NET Core library within the project it throws the Error: Could not load file or assembly System.Runtime 4.1.0.0
Here is the project Sample:
http://www.filedropper.com/game1_2
Is everyone else getting the same Error? How do I go about fixing this issue?
Kind regards, Josh L.
As #iinspectable said in the comments:
You cannot reference a full .NET assembly from a UWP project.
UWP is a thing on it's own, and is basically incompatible with .NET as it needs to run on all Win10 platforms (where .NET is meant to be run on Windows PC). Now i don't know monogame, but if it's a .NET Library, it's incompatible with UWP.

MonoMac Could Not Load Assembly or Dependency

I have a fairly simple application that I built using MonoDevelop 3.0/XCode 4.0/.NET 4.0 on OS X 10.7 (Lion). Basically, I have a Windows GUI and a Mac GUI for the application, and both share a class library. The class library is very simple (deliberately), and passes the MoMA tests with flying colors. My OS X GUI runs perfectly on my development OS X machine, but when I create a .pkg file and install it on a test OS X machine, it won't run at all. I have the Mono runtime installed on the test machine -- the runtime only, not the SDK or MonoDevelop. The application will open, but as soon as I make a call into the shared library, it fails with
System.IO.FileNotFoundException: Could not load file or assembly 'xxx' or one of its dependencies.
My shared library only has the following dependencies:
System
System.Configuration
System.Core
System.Xml.Linq
System.Data.DataSetExtensions
Microsoft.CSharp
System.Data
System.Xml
Surely the basic Mono framework supports all of these assemblies, right? What am I missing? I can't believe that releasing a simple application like this (via .pkg file, not AppStore) is so difficult! Could someone please point me in the right direction? Thanks.
OK, so, total noob/forehead slapping moment: the reason my application ran on my development OS X environment but not on the test box? .NET framework! I built the class library with Visual Studio 2012/.NET 4.5/Windows 7, checked it with MoMA, then copied it to my dev OS X, set a reference to it in my MonoMac project, and everything was fine, right? That's because that box had MonoDevelop and the .NET framework on it! When I created my .pkg and installed it on a new OS X box, the install was smart enough to download and install the Mono environment, but not the .NET framework, and who can blame it? The solution: build the class library against Mono 4.0, and use that assembly in my MonoMac release! Problem solved.
Thanks for help and comments. Please forgive the basic stupidity of this question: I'm not only a Mono/OS X noob, I'm a desktop development noob, too. I'm a web guy, for cryin' out loud!

Categories