System.Drawing.Common só é compatível com o Windows

O pacote NuGet System.Drawing.Common agora é atribuído como uma biblioteca específica do Windows. O analisador de plataforma emite um aviso em tempo de compilação para sistemas operacionais que não são Windows.

Em sistemas operacionais que não são Windows, a menos que você defina uma opção de configuração de tempo de execução, uma exceção TypeInitializationException é gerada com PlatformNotSupportedException como a exceção interna.

Comportamento antigo

Antes do .NET 6, o uso do pacote System.Drawing.Common não gerava avisos de tempo de compilação e nenhuma exceção de tempo de execução era gerada.

Novo comportamento

Do .NET 6 em diante, o analisador de plataforma emite avisos de tempo de compilação quando o código de referência é compilado para sistemas operacionais que não são Windows. Além disso, a seguinte exceção de tempo de execução é gerada, a menos que você defina uma opção de configuração:

System.TypeInitializationException : The type initializer for 'Gdip' threw an exception.
      ---- System.PlatformNotSupportedException : System.Drawing.Common is not supported on non-Windows platforms. See https://aka.ms/systemdrawingnonwindows for more information.
      Stack Trace:
           at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(String filename, IntPtr& bitmap)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(42,0): at System.Drawing.Bitmap..ctor(String filename, Boolean useIcm)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(25,0): at System.Drawing.Bitmap..ctor(String filename)
        /_/src/libraries/System.Resources.ResourceManager/tests/ResourceManagerTests.cs(270,0): at System.Resources.Tests.ResourceManagerTests.EnglishImageResourceData()+MoveNext()
        /_/src/libraries/System.Linq/src/System/Linq/Select.cs(136,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
        ----- Inner Stack Trace -----
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs(31,0): at System.Drawing.LibraryResolver.EnsureRegistered()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs(65,0): at System.Drawing.SafeNativeMethods.Gdip.PlatformInitialize()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs(27,0): at System.Drawing.SafeNativeMethods.Gdip..cctor()

Versão introduzida

.NET 6

Tipo de alteração interruptiva

Essa alteração pode afetar a compatibilidade com binários e a compatibilidade com a origem.

Motivo da alteração

Como System.Drawing.Common foi projetado para ser um wrapper fino em tecnologias Windows, sua implementação multiplataforma não é boa.

libgdiplus é o principal provedor da implementação multiplataforma do System.Drawing.Common no lado nativo. libgdiplus é efetivamente uma reimplementação das partes do Windows de que o System.Drawing.Common depende. Essa implementação faz com que o libgdiplus seja um componente não trivial. São cerca de 30 mil linhas de código C que não são testadas em grande escala e faltam muitas funcionalidades. O libgdiplus também tem inúmeras dependências externas para processamento de imagens e renderização de texto, como cairo, pango e outras bibliotecas nativas. Essas dependências dificultam ainda mais a manutenção e o envio do componente. Desde a inclusão da implementação multiplataforma do Mono, redirecionamos inúmeros problemas ao libgdiplus que nunca foram corrigidos. Em comparação, outras dependências externas que usamos, como icu ou openssl, são bibliotecas de alta qualidade. Não é viável elevar o nível do libgdiplus para que seu conjunto de recursos e sua qualidade sejam comparáveis com o restante da pilha do .NET.

Na análise de pacotes NuGet, observamos que o System.Drawing.Common é usado de modo multiplataforma principalmente para manipulação de imagem, como geradores de código QR e renderização de texto. Não observamos o uso de elementos gráficos pesados, pois nosso suporte a elementos gráficos multiplataforma está incompleto. Os usos de System.Drawing.Common observados em ambientes que não são do Windows normalmente são compatíveis com o SkiaSharp e o ImageSharp.

O System.Drawing.Common continuará evoluindo somente no contexto do Windows Forms e do GDI+.

Para usar essas APIs em aplicativos multiplataforma, migre para uma das seguintes bibliotecas:

Como alternativa, você pode habilitar o suporte para plataformas que não são Windows no .NET 6 definindo a opção de configuração de tempo de execuçãoSystem.Drawing.EnableUnixSupport como true no arquivo runtimeconfig.json.

Arquivo de modelo runtimeconfig.template.json:

{
   "configProperties": {
      "System.Drawing.EnableUnixSupport": true
   }
}

Arquivo de saída [appname].runtimeconfig.json:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Drawing.EnableUnixSupport": true
      }
   }
}

Observação

  • Essa opção de configuração foi adicionada para que os aplicativos multiplataforma que dependem desse pacote tenham tempo de migrar para bibliotecas mais modernas. No entanto, os bugs que não são do Windows não serão corrigidos.
  • Essa opção só está disponível no .NET 6 e foi removida no .NET 7. Para obter mais informações, confira A opção de configuração System.Drawing.Common foi removida.

APIs afetadas

Namespace de System.Drawing:

Namespace de System.Drawing.Drawing2D:

Namespace de System.Drawing.Imaging:

Namespace de System.Drawing.Printing:

Namespace de System.Drawing.Text:

Confira também