Runtime: 在 .NET Core 上支持完整的 System.Drawing 功能

创建于 2017-05-25  ·  103评论  ·  资料来源: dotnet/runtime

更新:以下是目前的计划。

  • [x] 将 .NET Framework 实现移植到 .NET Core。 WIP,请参见 dotnet/corefx#20593 。
  • [x] 将 mono 的基于 libgdiplus 的托管实现从mono 移动到 corefx
  • [x] 确保 mono 和 corefx 之间存在代码共享故事。 这可能意味着从 mono 中删除源代码并从已经存在的子模块链接中导入代码。 进行中。
  • [x] 端口 mono 对 System.Drawing 的测试,进行任何必要的修改以确保它们通过 Windows 实现,这是我们的兼容性基准。 进行中
  • [ ] 巩固了库的 Windows 和 Unix 版本之间的差异。 记录所有行为差异并适当标记测试用例。

System.Drawing 已被确定为 .NET Core 中缺少的最常用的程序集之一。 尽管有 3rd-party 替代方案提供相同功能的更现代版本( ImageSharpSkiaSharp等),但我们相信提供 System.Drawing 本身的二进制兼容实现仍然有价值。 此问题旨在记录和跟踪所涉及的工作项目。 还有很多悬而未决的问题; 鼓励反馈和建议。

优先事项:

  • 简化从 .NET Framework 到 .NET Core 的迁移。 我们需要二进制兼容(现有资产不需要重新编译),我们需要尽可能匹配行为。
  • 在 mono 的地方支持 System.Drawing,并促进我们的实现之间的代码共享。 作为其中的一部分,我们将开放 .NET Framework 的原始 Windows 实现。 这应该让我们能够改进 mono 的实现,并希望通过整合代码和努力来减少我们之间的维护负担。
  • 非目标:我们不将此库视为创新的机会,也不会投入大量精力来优化或重构它。 高性能、丰富的操作系统特定功能和重新设计的现代 API 不是我们有兴趣作为这项工作的一部分投资的领域。 有一些替代库可以解决所有这些问题以及更多问题。

    计划

System.Drawing 基本上是 Windows 上 GDI+ 组件的一个非常薄的包装器。 更糟糕的是,它不适用于 UWP 应用程序,因此支持仅限于 Win32 应用程序。 这使得跨平台实现变得困难,并且这项工作涉及的最大工作是弄清楚我们如何在所有平台上支持该库,并保持它们之间的兼容性。 我们可以利用几个现有的实现,但没有一个可以单独支持我们的所有平台。 我们可能需要几个不同的后端以获得完整的跨平台支持,尽管一些选项可以避免这种情况。 下图用平台适用性(列)映射了实施方法(行):

|Win32 | UWP | macOS | Linux / 其他
-----|--------|-------|---------|---------
.NET 框架版本 (GDI+) | ✓ | X | X | X
Direct2D/Win2D|✓|✓|X|X
Mono/libgdiplus|✓|X|✓|✓
Xamarin/CoreGraphics|X|X|✓|X
管理|✓|✓|✓|✓

.NET 框架版本 (GDI+)

这是 Windows 上 .NET Framework 的现有实现。 它是围绕 GDI+ 的一个非常薄的包装器。

  • :heavy_check_mark: 基线实现。 经测试,稳定。
  • :x: 只能用于非 UWP Windows 应用程序 (Win32)。

Direct2D/Win2D

为了获得 UWP 支持,我们可以在 Direct2D 或 Win2D 上实现兼容层。

  • :heavy_check_mark: GPU 加速
  • :x: 只为我们购买了对现有 .NET Framework 实现的 UWP 支持。
  • :x: 高实施成本
  • 可以在 Win32 和 UWP 应用程序之间共享(仅限 Windows 8+)。

单声道/libgdiplus

这是在单声道中使用的实现。 它使用一个名为“libgdiplus”的复杂原生 shim,它依赖于大量原生二进制文件。

  • :heavy_check_mark: libgdiplus 已经在 Unix 生态系统中的大量包管理器中可用。 这意味着我们可以像处理 .NET Core 的其他本机依赖项一样处理依赖项。
  • :x:本机代码为新开发人员增加了很多复杂性。

Xamarin/CoreGraphics

这是 Xamarin 使用的专门实现,用于支持 macOS 和 iOS。 与“libgdiplus”单声道版本不同,它仅使用 CoreGraphics(一个系统组件)。

  • :heavy_check_mark: 没有额外的原生依赖; 只使用系统库。
  • :x: 特定于 macOS。 可用于 iOS(.NET Core 尚不支持)。

托管(ImageSharp 或自定义)

一种选择是在托管代码中实现库。 我们可以调用现有的库,如 ImageSharp,用于图像处理和图形功能。 出于很多原因,这是非常可取的,但它确实具有更高的实施成本。

  • :heavy_check_mark: 可以在任何地方使用。
  • :heavy_check_mark:可以在任何地方实现统一的行为(以与 .NET Framework 的一致性为代价)。
  • :heavy_check_mark:长期降低维护成本。
  • :x: 高实施成本。

特定于 Windows 的

一种选择是将库视为特定于 Windows 的组件,类似于注册表。 尝试在其他平台上安装和加载库会像 Registry 一样抛出 PlatformNotSupportedException。

测试

我们在 .NET Framework 中没有很好的现有测试套件。 该库主要通过其他组件(如 WinForms)间接覆盖。 Mono 为它们的实现提供了一套很好的一致性测试,我们应该能够重用它们。 在适当的情况下,我们还应该考虑直接比较 .NET Framework 实现和其他实现的输出的测试用例(假设我们选择支持这些东西)。

地点

一个悬而未决的问题是这个图书馆应该住在哪里。 如果我们采取第三方依赖来支持某些平台,我们可能不希望这段代码存在于 corefx 中。

打印功能

上面略过的一件事是 System.Drawing 公开了许多用于打印图像和文档的功能。 这带来了与图像处理和图形不同的问题,它们可以移植地实现。 我们可能会决定排除库中所有与打印相关的部分。

未来投资

一旦所有平台都支持该库,我们将接受对该库的小规模、有针对性的改进,请记住,遗留兼容性是该库的唯一重要指标。 我们不希望合并任何重构、优化或增强 Windows 版本的代码,直到我们有一个完全有效的跨平台实现。 这与我们的策略与其他兼容性库相匹配,例如 System.IO.SerialPort。

@marek-safar @jimbobsquarepants @ViktorHofer @qmfrederik @karelz

Design Discussion area-System.Drawing enhancement

最有用的评论

值得用评论中提供的新信息更新原始问题。

Mono 的 System.Drawing 实现用于 Mono 的 Windows.Forms 实现,我们花了几年时间调整它以与各种第三方组件供应商合作。 我们将困难的图形问题委托给开罗。

它还被构建为在 Windows 上,它将使用系统提供的 GDI+ 库,而在其他平台上,它使用 Mono 的libgdiplus ,它通过让 libgdiplus 表面与 Windows libgdiplus 相同的 API 来实现这一点。

这意味着几件事:

  • Mono 的 System.Drawing 实际上是 libgdiplus 之上的一个非常薄的层。
  • 在 Windows 上,您可以使用真正的 GDI+,这非常好。

虽然实现有效,但字体处理能力在 Unix 上很复杂,所以我们使用 FreeType 来获取这些信息。 虽然这在 Linux 系统上效果很好,但在通常缺乏 FreeType 的 Mac 上首次使用时速度很慢,所以如果我要在这个领域做这项工作,我会从改进 libgdiplus 开始,以拥有一个可交换的字体后端并使用苹果在 OSX 上的 CoreText 避免了初始字体缓存创建问题。

Cairo 和底层库比您可以编写的任何 C# 代码都快。

也就是说,如果我要长期维护 System.Drawing,今天我会采取不同的方法。

我会使用 SkiaSharp 作为支持引擎,因为它针对 Chrome 和 Android 进行了积极维护、积极开发、积极微调和优化。 它还解决了 Cairo 的一些设计限制,包括 API 的瓶颈以及由于巨大矩阵变换导致精度损失而导致的坐标空间问题(Mozilla 经历了这一点,并且基本上也进行了这种转换) .

我将从sysdrawing-coregraphics开始,该项目将大部分逻辑从 libgdiplus 从 C 移动到 C#,并将对开罗的调用替换为对 CoreGraphics 的调用。

然后我会将对 CoreGraphics 的调用替换为对 Skia API 的调用。

去年我在业余时间沿着这些方向做了一些工作,在那里我主要是删除代码库,以便它可以在没有 CoreGraphics 的情况下编译,我计划添加 Skia 支持。 这样做的时间从未实现。 如果您对该叉感兴趣,可以在此处找到它。

所有103条评论

@mellinoe感谢您提供更多信息!

实际上,我在通过 CoreCompat.System.Drawing 使用 Mono/libgdiplus 方面有很好的经验。 原因如下:

  • Mono/libgdiplus 实际上确实在 Windows 上的 .NET Core 上运行。 在 Windows 上,Mono 的 System.Drawing 只使用 Windows 中的 GDI+。 所以我认为你可以为 Mono 的 System.Drawing 添加一个复选框到“Win32”
  • 我认为本机依赖项不需要成为问题。 libgdiplus 作为 .NET Core 支持的大多数操作系统的本机组件提供。 .NET Core 支持的所有 Linux 发行版都在其主线存储库中包含 libgdiplus: UbuntuDebianFedoraOpenSuse——甚至Alpine都有。 另外,libgidplus 最近也被添加到 Homebrew 中
    因此,我建议将 libgdiplus 视为从 Linux 发行版或 Homebrew 获取的单个本机依赖项 - 对其他 .NET Core 依赖项(例如 curl 或 OpenSSL)使用相同的获取机制。
  • Mono 的 System.Drawing 确实包含打印组件,因此您也可以免费获得这些组件。
  • Mono 的 System.Drawing 在 netstandard2.0 上本地运行(并且所有单元测试都通过!)并且非常接近在 netstandard1.6 上运行。
  • 您能否详细说明“本机代码为新开发人员增加了很多复杂性”?
  • 关于“行为和性能问题”,我并不是很了解它们,因此最好也将它们列出来。
  • 由于它是 Mono 的一部分,Mono 的 System.Drawing 仍在维护中。

另一种选择是使用 NetFX 的 System.Drawing 代码并让它在 Linux 上使用 libgdiplus 而不是 GDI+。 之前有一些关于开源 System.Drawing 的讨论,不确定这是否仍然是一个选择? 实施起来也相当容易。

关于UWP,您目前对UWP上的System.Drawing有需求吗?

/cc @akoeplinger

.NET Core 支持的所有 Linux 发行版都在其主线存储库中包含 libgdiplus:Ubuntu、Debian、Fedora、OpenSuse——甚至 Alpine 都有。 另外,libgidplus 最近也被添加到 Homebrew 中。

很高兴知道; 谢谢(你的)信息。 如果我们能够将它视为完全外部依赖,就像我们使用的其他本​​机库一样,那么我对使用它的犹豫就会减少。 我不是 libgdiplus 的专家,所以我当然想了解更多。 与我交谈过的人一直不愿轻易建议我们继续使用它,但面对不太有希望的替代方案,这可能没问题。 不过,总的来说,我认为我们应该非常谨慎地对待我们在 .NET Core 中采用的任何新的本机依赖项。 它们使我们和客户的很多事情变得更加复杂。

您能否详细说明“本机代码为新开发人员增加了很多复杂性”?

我试图表达这样一个想法,即尝试提交 System.Drawing 修复程序的人将比此处的托管 C# 库更难为外部 C 库做出贡献。 只是不同的技能组合而已。

之前有一些关于开源 System.Drawing 的讨论,不确定这是否仍然是一个选择? 实施起来也相当容易。

至少,我们将使用适用于 Windows 的 .NET Framework 版本,因此我们肯定会将其开源。 我们可以尝试在其他平台上对 libgdiplus 使用相同的实现,但我担心这会涉及重新编写大量本机代码。 再说一次,这只是我的猜测。

关于UWP,您目前对UWP上的System.Drawing有需求吗?

我们将 System.Drawing 视为阻止老客户(及其代码)迁移到我们的新平台(包括 UWP)的主要库之一。 这不完全是您提出的问题,但最终结果是:我们希望在任何地方都支持 System.Drawing,因为它已被证明是现有库的重要依赖项。

至少,我们将使用适用于 Windows 的 .NET Framework 版本,因此我们肯定会将其开源。 我们可以尝试在其他平台上对 libgdiplus 使用相同的实现,但我担心这会涉及重新编写大量本机代码。 再说一次,这只是我的猜测。

我的猜测是 .NET Framework 版本可以很好地与 libgdiplus 配合使用。 这是基于我使用 libgdiplus 的经验以及它如何尝试与 GDI+ 二进制兼容的假设。
不过,布丁的证明在于吃。 如果您可以在开源许可下提供 .NET Framework System.Drawing 源代码,我很乐意尝试一下,并在 libgdiplus 支持的 .NET Framework 的 System.Drawing 上运行 Mono 的 System.Drawing 单元测试在 .NET Core 上运行,比如说,Linux——这将给出明确的答案。

我试图表达这样一个想法,即尝试提交 System.Drawing 修复程序的人将比此处的托管 C# 库更难为外部 C 库做出贡献。 只是一套不同的技能,就是这样。

这是一个公平的观点,尽管另一方面,libgdiplus 使用的 C 库(例如 libpng、libjpeg 等)已经成熟了很长时间,因此也有一些价值。 无论如何,图形代码都需要特殊的技能组合,也许拥有该技能组合的大部分人都精通 C?

也许另一种选择是从 libgdiplus 开始并将代码从非托管移动到托管。 它可以通过重用 libgdiplus 来帮助启动 System.Drawing 实现,并逐步实现跨平台托管代码的目标。

也许另一种选择是从 libgdiplus 开始并将代码从非托管移动到托管。 它可以通过重用 libgdiplus 来帮助启动 System.Drawing 实现,并逐步实现跨平台托管代码的目标。

如果我要构建一个托管 2D 图形库(我是),我不会选择重新实现 System.Drawing API。

这就是说@mellinoe如果决定使用ImageSharp作为底层托管库,我很乐意提供并协助迁移。 尽管在 Jamestopia 中,我们不会打扰并积极推动开发人员迁移到更好的 API。 对于 MS 来说似乎更便宜、更容易。

这两个库目前的工作方式存在一些根本差异,必须讨论这些差异并考虑解决方法。 我们仍未完成,所以我们有很大的灵活性来改变 API 以提高灵活性并填补空白,这将有很大帮助。

像素格式
ImageSharp 将所有图像格式扩展为我们捆绑的20 种不同像素格式之一。 System.Drawing 以Format8bppIndexed格式和类似的索引形式存储图像。 必须开发一种解决方法来执行相同的操作。

图像格式

  • Gif - 我们的 gif 输出与 System.Drawing 不同。 我们支持动画 gif 和透明度,我们还默认使用八叉树量化输出并对结果进行抖动。 这都是可配置的,但我们必须限制我们的编码器使用默认的 System.Drawing 调色板。
  • Png - 我们使用所有可用的过滤器对 png 进行编码以减小文件大小,此外我们还支持索引 png。 我们可以添加一个开关来不过滤输出扫描线以使类型兼容。
  • Jpeg - 我们的输出与 System.Drawing 略有不同(我认为是由于解码时的舍入错误),我们的解码器性能不如刚才好。 我们需要在这方面的帮助以使其从头开始。
  • Bmp - 应该没有问题。 我们支持更多的输出类型,但这可能是有限的。
  • Tiff - 我们正在开发一种 tiff 格式。 正在取得巨大进展,但尚未完成

元数据
System.Drawing 将所有内容捆绑到PropertyItem类中,从 EXIF 元数据到 gif 循环计数和帧延迟,并且不会对这些数据进行解码。 我们已将元数据拆分为通用、EXIF 和 ICC 组件,并为这些数据类型提供完整的读/写。 您必须创建属性项以匹配该数据并存储原始字节。

仿射变换 - 调整大小、裁剪等
我们需要做一些工作来确保我们可以产生与 System.Drawing 相同的输出。 我不确定它用于不同质量枚举的采样器。 我们也不支持调整大小操作中的矩阵操作,因此必须在那里完成工作。

画画
我们提供具有与 System.Drawing 非常相似的 API 的绘图。 可能有一些差距,但我想。 我立即知道我们还没有实施所有的Hatch 灌木@tocsoft是我们在那里的常驻专家,因此他可以让您了解那里/不存在的内容。

我确定还有更多...

关于“行为和性能问题”,我并不是很了解它们,因此最好也将它们列出来。

@qmfrederik我对 libgdi 代码库进行了非常非常快速的扫描,并立即发现了不受支持的区域12 。 我不知道外面有什么。 我记得过去Image.FromStream(stream, useembeddedColorManagement)有问题,但我不知道这是否仍然是一个问题。

无论如何,图形代码都需要特殊的技能组合,也许拥有该技能组合的大部分人都精通 C?

顺便说一句,如果你拿枪指着我的头,我就无法读/写 C,而且我在编写 ImagSharp 时正在自学图形编程。 震撼😝

值得用评论中提供的新信息更新原始问题。

Mono 的 System.Drawing 实现用于 Mono 的 Windows.Forms 实现,我们花了几年时间调整它以与各种第三方组件供应商合作。 我们将困难的图形问题委托给开罗。

它还被构建为在 Windows 上,它将使用系统提供的 GDI+ 库,而在其他平台上,它使用 Mono 的libgdiplus ,它通过让 libgdiplus 表面与 Windows libgdiplus 相同的 API 来实现这一点。

这意味着几件事:

  • Mono 的 System.Drawing 实际上是 libgdiplus 之上的一个非常薄的层。
  • 在 Windows 上,您可以使用真正的 GDI+,这非常好。

虽然实现有效,但字体处理能力在 Unix 上很复杂,所以我们使用 FreeType 来获取这些信息。 虽然这在 Linux 系统上效果很好,但在通常缺乏 FreeType 的 Mac 上首次使用时速度很慢,所以如果我要在这个领域做这项工作,我会从改进 libgdiplus 开始,以拥有一个可交换的字体后端并使用苹果在 OSX 上的 CoreText 避免了初始字体缓存创建问题。

Cairo 和底层库比您可以编写的任何 C# 代码都快。

也就是说,如果我要长期维护 System.Drawing,今天我会采取不同的方法。

我会使用 SkiaSharp 作为支持引擎,因为它针对 Chrome 和 Android 进行了积极维护、积极开发、积极微调和优化。 它还解决了 Cairo 的一些设计限制,包括 API 的瓶颈以及由于巨大矩阵变换导致精度损失而导致的坐标空间问题(Mozilla 经历了这一点,并且基本上也进行了这种转换) .

我将从sysdrawing-coregraphics开始,该项目将大部分逻辑从 libgdiplus 从 C 移动到 C#,并将对开罗的调用替换为对 CoreGraphics 的调用。

然后我会将对 CoreGraphics 的调用替换为对 Skia API 的调用。

去年我在业余时间沿着这些方向做了一些工作,在那里我主要是删除代码库,以便它可以在没有 CoreGraphics 的情况下编译,我计划添加 Skia 支持。 这样做的时间从未实现。 如果您对该叉感兴趣,可以在此处找到它。

只是有一个想法。 服务器支持怎么样。 那里有什么计划? 这应该是任何决策的因素。

那么这里的目标是什么? 仅API兼容性? 这是我从@mellinoe所说的话中

如果是这种情况, @migueldeicaza本机代码和 C# 之间的比较不是很相关,只要 C# 性能不错:

Cairo 和底层库比您可以编写的任何 C# 代码都快。

我的意思是,如果在托管代码中构建 API 是一种选择,那么我们就去做吧。

另一方面,如果我们选择“让我们创建一些东西”选项,我们就不要选择仅限 Win32 的选项; 这让它有点混乱。

伟大的倡议!! 最好在一组接口之上实现 System.Drawing 并让社区开发每个实现。
例如,我们可以在 windows 上使用 DirectX,在 linux 和 mac OS 上使用 OpenGL。 但 System.Drawing 将在内部调用与平台无关的接口。
如果我们只选择 windows 选项,那么它不会对现有的 .net 框架产生任何影响。

您需要好的 API 才能使之成为一个可行的想法。 这是权宜之计,而不是解决方案。

我个人更喜欢一种更具前瞻性的方法,它为所有 .Net 平台提供官方支持的现代跨平台图形 API,以及基于它的通用和可选 System.Drawing 实现。 但我知道这是一个相当广泛且昂贵的解决方案,因此可能不切实际。

我很想在 ImageSharp 之上看到类似实现的东西。 这个假设的 System.Drawing 端口不是为了高性能或高质量使用——它只是为了移除一个用于移植遗留代码的阻塞器,其中图像处理可能是一个小功能。 如果它比原始的 netfx System.Drawing 慢,或者在所有操作中没有产生位相同的输出,那就没问题了——它甚至可以为一些很少使用的 api 抛出 NotSupported。

建立在具有现代 API 的社区库之上,将为人们移动他们的代码以在以后直接使用该实现提供一条前进的道路。

虽然我知道很多人都在使用 System.Drawing,但 WPF System.Windows.Media api 在许多方面的能力要强得多,而且与 UWP API 更相似,所以我个人更愿意看到更好、更灵活的/modern API 比 System.Drawing 可用,当然 System.Drawing 中可能有有价值的东西可能值得实现

恕我直言 System.Drawing 应该只保留为 Windows。 它已经在使用 ASP.Net Core 的 .Net Framework 项目中使用,但那些仍将使用 Windows,因为这些是企业应用程序,我认为他们不会移动整个基础架构,“因为现在他们可以”。

恕我直言 System.Drawing 应该只保留为 Windows。 它已经在使用 ASP.Net Core 的 .Net Framework 项目中使用,但那些仍将使用 Windows,因为这些是企业应用程序,我认为他们不会移动整个基础架构,“因为现在他们可以”。

我不同意。 ASP.NET Core 正被越来越多的开源项目和初创公司使用,因为与 nodeJS 相比,它具有跨平台支持和速度提升。 我认为在运行 .NET Core 和 ASP.NET Core 的所有环境中支持 System.Drawing 是可行的。

我有点担心这里的二进制兼容性。 我认为我们肯定需要一个与 .NET Framework 兼容的 System.Drawing 实现,但我也认为我们应该构建一些现代的、可扩展的和快速的东西(与社区一起)。 1. 将现有库移植到核心(托管)和 2. 构建 System.Drawing 的继承者可能是一个好主意,它具有当前 API 规范无法实现的所有创新和改进。

@ViktorHofer据说还有其他更现代的替代品,如 ImageSharp 或 SkiaSharp。 这就是为什么我认为这是毫无意义的,因为那些开源项目和初创公司应该使用其他替代方案。

@ViktorHofer在我生命的最后两年里,我一直在用 ImageSharp 做这件事。 它在许多方面已经比 System.Drawing 快,并且具有更简单/更容易扩展的 API。

它需要社区加紧帮助我推动它越过界限。 建造别的东西对我来说是一个沉重的打击。

@JimBobSquarePants那么我们当然也应该谈论建立在现有库的基础上👍如果你付出了很多努力,我们不应该将 ImageSharp 排除在讨论之外。

目标是什么?

  1. 是不是人们可以通过最少的更改将他们的应用程序从 Framework 迁移到 Core?
  2. 是不是人们可以将他们的应用程序从 Windows 上的框架转移到 Linux 上的核心?
  3. 是不是人们可以使用标记为以下内容的 api 开发新的服务器应用程序:
    > System.Drawing 命名空间中的类不支持在 Windows 或 ASP.NET 服务中使用。 尝试从这些应用程序类型之一中使用这些类可能会产生意外问题,例如服务性能下降和运行时异常。

我最初想象它是为了 (1) 人们不顾警告使用 System.Drawing; 但也许是(2)和(3)?

@JimBobSquarePants需要

这是相当令人反感的,并且考虑到 .NET Core 团队重新定义了“发布候选”的方式来表示“Alpha 实验技术预览”可能曾经意味着什么,现在任何人都可以猜测 .NET 世界中的“早期阶段”是什么(alpha)” 可能意味着,但听起来确实像是“我现在不想投入时间”。

如果您想清理 System.Drawing 用户的世界 - 我就是其中之一,有一个重要的(对我们而言)ASP.Net 应用程序,目前无法移植到 .NET Core,因为它依赖于,除其他外, System.Drawing - 那么您可能需要在该市场的光学器件上做一些工作。

  • 有一个带有绿色复选标记和红色十字的大特征表来显示 System.Drawing 的特征奇偶校验的当前状态,然后摆脱一般警告是否可行?
  • 你能进入 Nuget 而不是 MyGet 吗? (尽管标记为预发布?)
  • 您能否明确表示它适用于完整的 .NET,而不是人们需要挑选平台类型?
  • 不要公开承认你在使用这个库时自学了图形编程。 :-)

我不想看到任何人遭受“毁灭性打击”,尤其是像 MS 这样的近视厚皮动物的意外打击,但我今天早上去看了 ImageSharp 并气馁地离开了。

我会选择阻力最小的路径 - 确定哪种情况最便宜并这样做。 到处警告它只是不应该用于新项目的兼容层。 如果对剩余的人力感到难过,请投资于改进 ImageSharp :)

@willdaen出于好奇,您是否看过 CoreCompat.System.Drawing(Mono 的 Sysyem.Drawing 移植到 Core)? 那能满足你的要求吗?

@Kukkimonsuta是的,这就是我认为的内容 - System.Drawing 的跨平台应用,人们可以(暂时)在迁移到 .NET Core 时使用它 - 基本上消除了其中一个采用阻止程序。

它可能不是最纯粹的解决方案,但它是 libgdiplus 的构建目标。

@willdean

今天早上我去看了 ImageSharp,然后气馁地离开了。

真的吗? 嗯,这太令人失望了。

您没有看到自述文件链接的

您能否明确表示它适用于完整的 .NET,而不是人们需要挑选平台类型?

它在自述文件中。

基于 .Net Standard 1.1 ImageSharp 构建,可用于设备、云和嵌入式/物联网场景

该消息的含义正是它所说的。 API 可能会发生变化。 (顺便说一句,我认为 MS 没有重新定义任何东西,他们只是匆匆忙忙地做事,但 alpha、beta 等不是由他们定义的)

需要做些什么来删除“处于早期阶段(alpha)。因此,在库达到候选发布状态之前,我们无法支持它在生产环境中的使用。” 来自你的项目的警告?

我们需要做两件事。

  1. 重构jpeg 解码器以减少内存使用并加快速度。
  2. IPixel接口更改为不从字节打包/解包,而是使用预定义的结构。 RGBA32、RGB24、BGRA32、BGR24 并且还使用 refs 进行 Vector4 打包/解包

之后,我很高兴进入测试版并将库添加到 Nuget。

这是一个非常缓慢的 alpha,因为我想把它做好。 创建一个半/烘焙的图形库根本没有意义。 没有人会使用它,你最终会浪费你的时间。

PS 我并不羞于承认我是边做边学的。 这是彻底了解 IMO 事物的绝对最佳方式,我认为这是对其他人也可以这样做的一种鼓励。 😄

@JimBobSquarePants感谢您的回复 - 我真的不愿意通过专门扩展关于 ImageSharp 的讨论来劫持这个线程......我会尝试一下并在您的回购中提交任何问题。

@qmfrederik我没有看过 CoreCompat.System.Drawing - 我们在几件事上受阻(SignalR 是另一个)而且我并没有真正努力寻找所有缺失的替代品 - 我只是模糊地关注什么发生在我知道会导致我们问题的事情上。

任何人都提供了很多很好的反馈,谢谢! (我没有赶上所有的)

以下是我如何看待System.Drawing优先级和选项:

优先事项

  1. System.Drawing主要目标是简化从桌面到 .NET Core (在 Windows 上)的
  2. 第二级目标是在需要的地方支持System.Drawing —— 目前 Mono 在 Mac 和 Linux 上需要它(Mono 正在尝试重用 CoreFX 库/源代码,因此需要协同作用)。

    • 注意:Mono 对 iOS 有额外的要求——尺寸必须很小(即它需要使用 Mac API——@marek-safar 来确认我是否没有将它与我们关于 HttpClient 的讨论混淆)。

  3. 第三级(延伸)目标是在 .NET Core 上简化从 Windows 到 Linux/Mac 的迁移

    • 注意:轻松迁移并不一定意味着出色的性能。

  4. 非目标是高性能、丰富的操作系统特定功能、现代 API 表面等(任何未在 (1)-(3) 中列出的内容)。

解决方案

(2) Mono 在 Mac 和 Linux 上需要它

  • 从我们与@marek-safar 的聊天中,我们了解到 Linux 上的 Mono 实现非常复杂——它需要为特定版本的发行版(甚至不仅仅是发行版,而是它们的版本)进行特殊构建。
  • 我们同意@marek-safar,Linux 实现的复杂性不是我们应该尝试移植到 CoreFX 的东西(由于成本高,价值低)。 我们应该准备简单的迁移路径(见(3))。
  • @migueldeicaza这与您的回复有何一致? libgdiplus是@marek-safar 告诉我的复杂作品吗? 是否有不将该部分迁移到 CoreFX 的可行选项?

(3)简化从 Windows 到 Linux/Mac 的迁移

  • 易于实现的平台(例如 Mono 的 Mac 实现),我们应该只是实现。
  • 对于由于成本/收益而无法实施的平台,我们应该建议迁移到 3rd 方库( ImageSharpSkiaSharp等)。
  • 为了让开发人员更容易迁移,我们可以投资在库顶部伪造旧的System.Drawing API 表面的shims 。 不过,垫片可能位于不同的命名空间中(例如SkiaSharp.Drawing.Compat ),因此需要进行小的代码更改和/或交叉编译。 垫片可能应该位于库存储库中,或者位于单独的存储库中(不绑定到 CoreFX 本身以避免 CoreFX 对库的依赖)。

@karelz关于 Linux 上的 Mono 实现,我认为它根本不涉及。 事实上,本机部分 libgdiplus 随 .NET Core 支持的所有 Linux 发行版一起提供。 所以你不需要移植它,发行版已经为你做了。 您可以像对 openssl 或 curl 所做的几乎相同的方式声明对 libgdiplus 的依赖 - 通过发行版而不是 NuGet 获取它。

您可以考虑将 libgdiplus 及其依赖项作为 NuGet 包中的本机组件进行分发。 这确实变得复杂,快速 - 我尝试使用 CoreCompat.System.Drawing。

Mono/libgdiplus 几乎免费为您提供 1、2 和 3 - 大部分工作已经完成。 结果在 CoreCompat.System.Drawing NuGet 包中。

@qmfrederik我只依赖于在 Mono 上工作的 @marek-safar 的信息 - 所以我让他插话。

@qmfrederik先生是对的,libgdiplus 已经在几乎所有 Linux 发行版上可用,它只依赖于非托管部分。 如果 Marek 有关于处理构建复杂性的任何反馈,那么您将尝试发布您的分叉版本,然后您将遇到与发布 CoreCLR 相同的问题 - 即您需要为每个系统进行编译.

因此,如果您想以最快/最简单的方式引入 System.Drawing,这应该不是问题。

你不必担心 iOS,因为历史原因 System.Drawing 没有在那里使用,我们甚至不分发它(除了基本的 Rectangle、Point 类型)。

在 iOS 上,无论是 CoreGraphics 还是我们的跨平台 SkiaSharp,世界都已经改变了。

鉴于@karelz概述的优先事项,我会改变我的建议。 考虑到这些优先级,实际上 System.Drawing 不会成为图形的长期基础,我基本上只是重用 Mono 代码。

依靠 gdiplus,并使用 Mono 的 System.Drawing 堆栈(以及 ifdef 输出在 .NET Core 2 上不起作用的部分)。

您当然可以选择不同的路径,但鉴于上述目标,听起来投资重写此代码是在浪费时间。

考虑到这些优先级,实际上 System.Drawing 不会成为图形的长期基础,我基本上只是重用 Mono 代码。

这也是我的想法。 需要注意的是,我们可能希望在 Windows 上使用桌面实现以获得更高置信度的兼容性(我最近被 HttpListener Mono 兼容性咬了,所以我现在有点谨慎;))。

鉴于上述目标,听起来投资重写此代码是在浪费时间。

同意。 我们没有计划巨额投资。 而且我不喜欢浪费精力。

总的来说,我不认为System.Drawing是我们想要对其进行创新的如此出色的 API 和实现——SkiaSharp、ImageSharp 等其他项目已经这样做了,所以让我们依靠它们为未来的未来创新图形空间。 我们不应该在 CoreFX 中重新发明轮子,除非有很好的理由。 一个 .NET 生态系统来统治它们! ;)

Mono 的 System.Drawing 方法的优势在于它调用了本机 GDI+,因此在 Windows 上,您可以使用系统附带的方法。 如果我们获得批准发布 .NET 的 System.Drawing,您也可以将其换掉。

(我最近被 HttpListener Mono compat 咬了,所以我现在有点谨慎;))。

感觉是相互的@karelz ,Mono也被CoreFX中的代码咬了:-)

我同意与 Mono 共享更多代码/库总体上是有益的。
如果我们可以解决 Windows 上的兼容性问题(可能需要进行大量测试),我就可以采用这种方法:)

感觉是相互的@karelz ,Mono也被CoreFX中的代码咬了:-)

当您遇到这些案例时(或者如果您有过去的清单),请将反馈发送给我们/我。 虽然通常无法立即采取行动,但防止将来发生此类不幸情况至关重要。 如果不了解此类情况,我们将无法完全了解我们对 Mono 的影响,我们可能会继续做我们正在做的事情,一遍又一遍地给您带来同样的痛苦。 让我们努力防止这种情况发生。

接下来的步骤是什么? 从 Mono 的源代码为 .NET Core 构建 NuGet 包很简单,设置 CI 和测试也应该如此。 Mono 会生成包还是将代码导出到 dotnet 下的单独存储库? 如果可能的话,还有摄取 NetFX 代码的工作。

@karelz您担心与 Windows 兼容的哪一部分? 就像我说的,我们的 System.Drawing 是 GDI+ 之上的一个薄层,所以在 Windows 上,它是 Windows GDI+ 完成所有繁重的工作。

我们的实施中可能存在差距(在托管和非托管方面),应该填补这些差距。

也许我们拥有的最全面的测试是 Mono 的 Windows.Forms 实现,它在纯 GDI+ 之上模拟整个工具包(甚至在 Windows 上)。 还有另外两个测试套件,一个已经到位的单元测试套件,用于测试 GDI+ 的一些元素,另一个用于图像输出的模糊比较,后一个测试套件需要恢复生机。

从逻辑上讲,我希望在 Mono 和 .NET Core 上编译相同的源代码树,以最大限度地共享代码,并避免分叉,因为这是一个单元。

让我们首先说我们应该添加适当的 ifdef 以使源代码针对 .NET Core 和 Mono 进行编译。

  • 我们可以将 System.Drawing 保留在 Mono 中,并进行修改以针对 .NET Core 添加构建工具以生成适合发布(最简单)的 NuGet。

  • 我们可以将 System.Drawing 提取到一个单独的 git 模块中,以保留历史记录并使 Mono 和 CoreFX 都具有依赖项。

  • 我们可以直接将源代码复制到 CoreFX 中,然后将 Mono 切换到它,但是我们会丢失与之相关的源代码控制历史记录,以便后代进行调试。 也许第一次提交应该指向一个单声道/分支,这样人们就可以在那个时候恢复考古调试。

@migueldeicaza Mono 的 System.Drawing+libgdiplus 已经在 .NET Core 上编译和运行,这是因为@qmfrederik在上周/几个月内发送了一些很棒的 PR :)

我同意从 .NET Framework 开源托管 System.Drawing 层会很棒,这样我们就可以替换我们的托管层并更加兼容(我假设大部分工作是由 .NET Framework 中的底层 gdiplus 完成的)也实施)。

这意味着在 Windows 上你最终会得到一个高度兼容的版本,而其他平台下面有 Mono 的 libgdiplus。 转移到一个单独的 repo 或进入 corefx 对我来说听起来不错。

当然,我们应该推广 ImageSharp 等作为现代替代品!

感谢大家提供的所有精彩反馈。 我将尝试总结讨论的要点,并尝试澄清一些事情。

  • 图书馆的目标。 这整个努力_严格地_是为了兼容性。 我认为 Karel 很好地描述了优先事项,尤其是非目标。 我会将这些信息复制到顶部的原始帖子中。 重要的是,我们不认为这是创新或以任何方式重新发明轮子的机会。 已经有非常优秀的社区项目由非常聪明、积极和敬业的人推动; 我们没有理由破坏这些努力。

  • libgdiplus:我最初没有的一个重要信息是 libgdiplus 已经在 Unix 生态系统中的大量包管理器中可用。 包括像 Alpine 这样的发行版。 这使得将其视为“任何其他本机依赖项”是可行的,并期望用户从他们系统的包管理器中下载它。 我最初的信念是它总是与 mono 捆绑并安装,这会使 .NET Core 更难以依赖。

  • .NET Framework 的 System.Drawing 版本。 一些人提出了这个问题,我只是想澄清一下:我们已经“提前”开放了 .NET Framework 中正在使用的 Windows 实现。 我已经编译并运行了一些测试,但是在共享之前我需要对代码进行通常的清理和“清理”,因为它来自我们内部的封闭源代码库。 我现在要做一些测试,看看当我尝试在 Ubuntu 上针对 libgdiplus 运行我们的 .NET Framework 实现时会发生多少爆炸。

  • UWP 支持:实际上,我认为我们将为此获得 UWP 支持的唯一方法是,如果我们围绕 UWP 上可用的 API 或托管实现编写某种包装器。 我现在同意将其排除在讨论之外(以及最初的 .NET Core 实现),但我希望我们在考虑我们正在进行的投资时牢记这一点。 如果我们最终要对代码进行大量更改或重写,我们应该以支持 UWP 的方式进行。

@mellinoe如果您想尝试一下,请查看此处的代码: https :

无论发生什么,请确保它 100% 在 Azure 中工作。 GDI+ 现在受到高度限制,大多数 PDF 库通过 System.Drawing 依赖于此

@JimBobSquarePants我拥有几个 NuGet 包(SharpAdbClient、RemoteViewing、CoreCompat.Selenium),它们在公共 API 的某个地方返回图像(实际上是截图)。 这些包不处理图像——这些包的使用者将进行图像处理。

目前,它们依赖于 System.Drawing 并返回一个Image对象。 这会造成对 System.Drawing 的严重依赖,这是我不一定想做的事情。

所以我试图弄清楚我(以及我猜遇到相同用例的其他人)可以做些什么来确保我的包对 System.Drawing 没有硬依赖,并让我的消费者决定如何处理图片。

我现在能想到的唯一选择是

  • 返回一个byte[]Stream对象,这似乎不是最理想的,因为它没有给我一个选项来传达 1) 我正在返回一个图像对象和 2) 一些图像元数据(至少是哪个编解码器,...)。
  • 同意 netstandard 中的某种基类,它包含一个字节数组和必要的元数据,以便其他库可以处理它
  • 让 ImageSharp 和其他人实现某种“System.Drawing 桥”——即您可以使用System.Drawing.Image ,然后将其转换为您自己的 Image 类。

想法?

@qmfrederik

我认为像@karelz所描述的那样 - 兼容包将是我的回购中最好的主意。 我们还通过从流和通用原语加载/保存来桥接图像。

你们做得很好! 保持。
通过阅读此线程,我理解的一件事是将 system.drawing 移植到 .Net 核心并保持交叉兼容性并不容易。

由于 .Net 核心已经与现有的 .Net 框架不兼容,如果我们从头开始实现 API 的最小化怎么办。 其中包含特定于平台的 API 或通用的跨平台库。 (开罗)
我主要关心的是我们不应该失去 .Net 核心对功能的交叉兼容性。
我不是在提倡不要针对system.drawing来实现,但是我们不应该为了遗留代码的兼容性而失去交叉兼容性。(但如果我们能同时实现还是很好的)

再次干得好.Net 核心团队。

我们不应该为了遗留代码的兼容性而失去交叉兼容性

@vibeeshan025我的理解是 System.Drawing 是为了遗留代码兼容性而提供的,它是一个遗留 api。 所以兼容性是最高标准。 对于新代码,鼓励使用替代 API。 它在 UWP 上不可用,并且对于某些应用程序明确不鼓励:

不支持在 Windows 或 ASP.NET 服务中使用 System.Drawing 命名空间中的类。 尝试从这些应用程序类型之一中使用这些类可能会产生意外问题,例如服务性能下降和运行时异常。

@mellinoe非常清晰的总结! 👍

托管(ImageSharp 或自定义)

一种选择是在托管代码中实现库。 我们可以调用现有的库,如 ImageSharp,用于图像处理和图形功能。 出于很多原因,这是非常可取的,但它确实具有更高的实施成本。

投票支持这个选项。 我敢打赌图像大小调整和裁剪是 80%。 我假设两者的实现都是纯粹的计算,不依赖于任何特定的操作系统特定的 API,即使有一些 GPU 加速版本,我敢打赌有一个非加速版本。 也许有一个选项可以从 Windows 中提取相关的本机实现代码,使用它来创建一个小的跨平台库。 开源它会很好,但不要认为很多人会关心它的工作时间。

@karelz @mellinoe我认为最好开源 .NET System.Drawing 并在 Windows 上的 netcore 和 Mono 上使用它。 这会毫不费力地带来 100% 的兼容性。

在 linux 上,我担心您会陷入与使用 OpenSSL 依赖项相同的陷阱,如果您的库仅用于向后兼容解决方案,那么这可能不会那么糟糕。

OSX 在这里基本上被忽略了,但是具有 libgdiplus 依赖项肯定不会带来流畅的体验,因为它带来了整个 X11(不再是 OSX 的一部分)依赖项,使得独立的应用程序构建变得棘手。

@marek-safar 关于 macOS 和 x11,您现在可以在没有 X11 的情况下为 macOS 构建 libgdiplus通过 Homebrew 获取 libgdiplus

libgdiplus 的部署将类似于 OpenSSL 依赖项,具有其所有优点和缺点。

@qmfrederik没错,但这会禁用 X11 功能,这些功能在快速检查时会破坏 DPI 缩放。

@marek-safar 是的,(自动)DPI 缩放不适用于 macOS 上的 libgdiplus。 我假设在 Mac 本身上使用 WinForms 或其他 UI 时,您只需要真正需要 DPI 缩放; 并且在 ASP.NET Core 或 CLI 工具中使用 System.Drawing 时,这不会是什么大问题(如果有的话)?

@JimBobSquarePants

那么我们在哪里呢?

使用 libgdiplus 一段时间看起来很有希望,但据我所知,有两个明显的问题。

  1. Mono System.Drawing 中的功能缺失或损坏
  2. 在服务器上使用库。

我们都阅读了警告,但到目前为止一直忽略它。 我们不能向迁移开发人员推荐肯定可以在服务器上使用兼容包吗?

@qmfrederik部署 libgdiplus 将类似于 OpenSSL 依赖项,具有其所有优点和缺点。

我们摆脱了对 Mac 的 OpenSSL 依赖,主要是由于 Mac 用户的强烈反馈。 我不想遵循相同的路线(取决于 Homebrew 安装的依赖项,Homebrew 可能会破坏)。
如果 Mac 代码需要的东西不是操作系统的一部分,我们不应该让它成为 CoreFX 的一部分,以避免另一场噩梦和“不同”/“特殊”。 (如果我不明白所有的细微差别,请随时给我打电话 -
我的主要目标是为了简单而优化,复杂性通常会反过来)

总体:在我看来,Mac 没有简单的解决方案。 如果这是正确的,我建议依赖 3rd 方库垫片(请参阅 https://github.com/dotnet/corefx/issues/20325#issuecomment-304315828)。

@marek-safar 你说 Linux 和 OpenSSL 有同样的问题是什么意思? 总的来说,我们在 Linux AFAIK 上不太介意(在 Mac 上更糟)。
@janvorli你能评论一下我们对 Linux 依赖 OpenSSL 的立场吗? 我想我们已经和它和平相处了,对吧? 最大的缺点是什么,我们应该如何考虑添加这样的另一个依赖?

@karelz嗯,我不确定我是否遵循 - 为什么 openssl 在 macOS 而不是在 Linux 上有问题? 我认为要求用户运行brew installapt-get install之间没有太大区别。 不过,您得到的反馈似乎有所不同?

我知道自制软件将 openssl 文件从一个文件夹移动到另一个文件夹存在一些问题; 我认为 libgdiplus 不太可能发生这种情况。

或者,对于 macOS,您可以考虑将libgdiplus.dylib文件作为 NuGet 包中native/osx-x64文件夹的一部分进行分发。 我需要检查一下,我认为 libgdiplus 对 mac 没有非操作系统依赖性,所以这是一条可行的路线。

这将带您进入这个部署场景:

  • 托管代码:

    • 在所有平台上使用 System.Drawing(最好来自 NetFX)

  • 原生代码:

    • Windows:使用 GDI+

    • Linux:通过包管理器需要 libgdiplus

    • macOS:作为 NuGet 包的一部分提供libgdiplus.dylib

参见 dotnet/runtime#17872 和 dotnet/runtime#17597 - 依赖的传递机制是不同的 AFAIK。

重新分发更多的组件意味着在传送安全更新方面需要做更多的工作。 我们不重新分发 OpenSSL、libcurl 的原因之一(关于这个话题有很多争论和反复讨论)。

如果我们可以依赖像 OpenSSL/libcurl 这样的东西作为依赖来部署,那么它可能是一个不错的选择。 我让@mellinoe研究选项并提供建议。

看看这些问题,问题的一部分似乎是 OS X 曾经包含 openSSL,而 Apple 正在远离它。

我认为 libgdiplus 不会有同样的问题,因为它不是 OS X 的一部分,而是“纯粹的”第 3 方库。

我最后的小更新:

  • 我将专注于合并 Windows 版本,可能在接下来的一两天内。 该计划仍将使用 .NET Framework 中的现有实现。 正如我之前提到的,我已经构建了它,但我需要对代码库进行与开源相关的清理。
  • 为库添加一个基本级别的测试,从 mono 借用测试用例。 测试用例需要修改,因为它们不会针对 Windows 实现按原样通过。
  • 在测试的同时,开始从https://github.com/mono/mono通过 libgdiplus 移植托管包装器
  • 至于 macOS 上的 libgdiplus 依赖项有问题——我认为它与 OpenSSL 依赖项略有不同。 那里似乎不鼓励使用 OpenSSL,但我认为 libgdiplus 没有任何此类问题。 它只是一个应该很容易安装的普通库。 总是可以选择使用基于 CoreGraphics 的实现,但让我们先从 libgdiplus 开始,因为它更容易。

@JimBobSquarePants我同意 Azure 中的 GDI+ 限制令人不安。 我想了解限制究竟是什么,以及它适用于哪些 Azure 产品。 我最初的理解是限制仅适用于 Azure Web 应用程序。 这里的问题是,它一直明确表示不支持在服务器场景中使用 GDI+ 和 System.Drawing,因此该限制不应该令人惊讶......

我们可能会与 Azure 合作,将某些 API 列入白名单......我认为。

2017 年 5 月 30 日,星期二,下午 12:01,Eric Mellino通知@ github.com
写道:

我最后的小更新:

  • 我将专注于合并 Windows 版本,
    可能在接下来的一两天。 计划仍然使用现有的
    .NET 框架的实现。 正如我之前提到的,我已经有了
    它正在构建,但我需要对代码库进行与开源相关的清理。
  • 为库添加一个基本级别的测试,从
    单核细胞增多症。 测试用例需要修改,因为它们没有按原样通过
    反对 Windows 实现。
  • 在测试的同时,开始移植“libgdiplus”
    从单声道实现。 我相信我们应该转移到一个所有
    来源是从 corefx 共享的。 我相信单声道已经消耗了一些
    来自 corefx 的代码,但我们不做相反的事情。
  • 至于 libgdiplus 依赖项在 macOS 上有问题——我愿意
    认为它与 OpenSSL 依赖项略有不同。 使用 OpenSSL
    似乎在那里被积极劝阻,但我认为没有
    libgdiplus 的此类问题。 它只是一个普通的图书馆,应该是
    易于安装。 总是可以选择使用
    而是基于 CoreGraphics 的实现,但让我们从 libgdiplus 开始
    首先,因为它更容易。

@JimBobSquarePants https://github.com/jimbobsquarepants我同意
Azure 中的 GDI+ 限制令人不安。 我想了解什么
正是这些限制,以及它适用于哪些 Azure 产品。 我的
初步阅读是限制仅适用于 Azure Web 应用程序。 这
房间里的大象是它一直清楚地传达了这样的信息
GDI+ 和 System.Drawing 不支持在服务器场景中使用,因此
限制不应该令人惊讶......


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/dotnet/corefx/issues/20325#issuecomment-304975429
或静音线程
https://github.com/notifications/unsubscribe-auth/AAALTGdI8Aoog2-R5sg9ZhOGd9EhK8CCks5r_GeUgaJpZM4NmyU5
.

——
斯科特·汉塞尔曼
捐赠抗击糖尿病: http :

我认为微软没有抓住重点(可能是错误的)

我们,客户,真正需要的是“微软官方推荐的用于 Windows、Linux 和 Osx 图像处理的库”。

我的建议:

  1. 微软将 ImageSharp 等库(或任何适合的库)推入生产就绪型。
  2. 为调用底层库的非常常见/高使用率的 API 创建一个System.Drawing.Compat

虽然官方方式不存在,但客户仍然会说(包括我在内)需要System.Drawing

@Bartmax如果发生这种情况会非常好。 (我真的可以在帮助下做,你知道,OSS 和所有这些)但是牌堆在它上面。

我个人认为构建这个会发出错误的信息,我真的,真的希望它不会发生。 一旦包含 System.Drawing,开发人员就没有动力从 System.Drawing 转移,我们都知道它将继续在服务器上使用。

它会扼杀我工作的任何采用率。 😞

ImageSharp 是 MS 证明其新的以性能为导向的库Vector, Matrix etcSpan<T>的强大功能的绝佳机会,并且还可以在现实环境中测试其 API。 在没有帮助的情况下,该库没有理由无法在所有平台上快速运行,并为试图在 .NET 中使用图形库的开发人员带来更好的环境。 我很痛苦,这个机会被忽视了,让我感到沮丧的是我得到的帮助太少了。

我已经忘记了我在野外发现的泄漏的、深思熟虑的、复制/粘贴的 System.Drawing 示例的数量(这就是我最初编写 ImagProcessor 的原因)。 这当然不是我们应该鼓励的事情。

IMO 采用 netcore 的最大痛点不是缺少库。 这是工具。 使用不需要不断重新打开解决方案的 IDE 和更快、更好的测试环境,缺少库会更快。

我想使用的工具,已经在使用 GDI+。 所以对 System.Drawing 的更改对他们来说并不重要。

至于可以使用新 System.Drawing 的工具,如果没有来自社区的严重压力,他们不会重写自己的工具包以使用新模型实现事物。 我不知道如何得到蛋糕并吃掉它……但这确实是一个非常复杂的问题。

@JimBobSquarePants

IMO 采用 netcore 的最大痛点不是缺少库。 这是工具。 使用不需要不断重新打开解决方案的 IDE 和更快、更好的测试环境,缺少库会更快。

对此 +100。 我试图用 ImageSharp 帮助@JimBobSquarePants ,但被 Core-Pox 彻底打败了。 Resharper 不会运行测试,NCrunch 不会运行测试,覆盖工具不起作用,并且将所有问题放在上面,将 ImageSharp 引入 netfx 项目导入如此大量的(损坏的)依赖项项目完全停止运行。 我不认为这很大程度上是 ImageSharp 的错,公平地说,相当一部分不是 corefx 的错,但它是今天的现实。

我实际上真的很想帮助 ImageSharp(就目前而言,它还没有为我们的应用程序做好准备),但我不能容忍 100:1 的bollocks:coding比率。 而且在前 20 名接触过的 corefx 贡献者名单中(这是侥幸,但仍然......),所以天知道@shanselman在林业部的伙伴是怎么

@JimBobSquarePants是否因为世界没有找到通往他的图书馆的道路而受到伤害和失望都没有关系,这很艰难。 如果他的项目因为 MS 生态系统的糟糕状态而无法完成,这很重要。

我并不假装了解 MS 目前的结构,但无论是谁坐在 .NET 和 VS 团队之上,都需要用足够的力量将一些人粉碎在一起,以便 CERN 的人过来查看碎片。

@mellinoe如果 Linux 上 libgdiplus 的主要交付机制是 Linux 发行版,请记住,所有发行版目前都将https://github.com/mono/libgdiplus视为上游存储库。

找到一种使 libgdiplus 的 CoreFX 和 Mono 版本保持同步的方法可能很有趣(例如,通过分叉和移植上游,或仅使用上游存储库)

我认为人们可以理解有两种 System.Drawing 实现 - Mono 一种和 .NET 一种。 我认为 Mono 实现一经开源就会开始向 .NET 趋同。

有两个 libgdiplus 实现会令人困惑。

对于 GDI+ 不可用的 Windows 环境(Azure 和 Nano 服务器?),libgdiplus 也可以在 Windows 上使用。

你说 Linux 和 OpenSSL 有同样的问题是什么意思? 总的来说,我们在 Linux AFAIK 上不太介意(在 Mac 上更糟)。

@karelz我的意思是你需要依赖发行版包管理器来准备依赖项,但我想对于 Linux 来说这没问题。

@qmfrederik我的假设是,正如您之前提到的,我们将只有另一个外部依赖项(libgdiplus):

您可以像对 openssl 或 curl 所做的几乎相同的方式声明对 libgdiplus 的依赖 - 通过发行版而不是 NuGet 获取它。

但是,如果 libgdiplus 是 Mono 的一部分而不是发行版的一部分,它可能会影响/使我们的从源代码构建工作复杂化。 @mellinoe你能戳一下吗?
这听起来像是支持 Linux 的巨大成本增加。 如果是这种情况,我宁愿不支持 Linux,而是依赖上述 3rd 方库的垫片。

@karelz libgdiplus 是 Mono 的一部分,它由 Linux 发行版作为包管理系统中的一个包分发。 很像 libcurl 和 openssl 是他们自己的项目,但由 Linux 发行版重新分发。

完全清楚,今天您可以在 vanilla Ubuntu 和 Debian 上执行apt-get install libgdiplus ,在 vanilla CentOS 和 RHEL 上执行yum install libgdiplus ,仅举几例。

所以我对@mellinoe谈论将 libgdiplus 导入 corefx 源代码树感到有些困惑。 我没想到会发生这种情况,就像在 corefx 源代码树中也没有导入 libcurl 和 openssl 一样。

@qmfrederik在我的上https://github.com/mono/libgdiplus移到任何地方。

@mellinoe有道理,感谢您的澄清!

当然使用SkiaSharp作为后备引擎是最好的选择。

  • 成熟稳定的代码库
  • 最佳表演
  • 最受支持的平台
  • 积极维护
  • 文本和字体处理
  • 软件和 openGL 渲染都支持非 DX/GDI 平台上的快速图层组合
  • 已经处理了许多 2D 图形文件格式(包括 SVG)

我(非常强烈)认为,如果我们决定重写库的重要部分,那么我们应该使用纯托管代码,而不是像 SkiaSharp 这样的本机包装器。 我已经在上面提到过,但这是我的推理:

  • 托管代码比本机包装器“更具可移植性”。 根据定义,它可以在运行时运行的任何地方工作,而 Skia 需要为不同的平台重新编译。
  • 目前尚不清楚 Skia 是否可以以我们需要的“便携式 Linux”方式编译,以便在 .NET Core 中使用。 至少它代表了额外的工作。 Libgdiplus 在这里是可以接受的,因为它在我们关心的发行版的大多数/所有包管理器中都可用。
  • 尽管 Skia 速度非常快,并且可以利用 GPU 进行加速,但我认为对于像这样的兼容性库来说,这不是一个高优先级。

在任何情况下,当前的计划只是重新使用 System.Drawing 的现有实现,而不编写任何超出要求的新代码。 如果我们决定出于某种原因确实需要重写库的大部分内容,就会出现上述情况。

这是什么状态? 只计划支持 .net framework、mono、.net core 并离开 UWP?

@John0King是的,没错。 目前,我们还没有确定一种在不重新实现整个库的情况下支持 UWP 的好方法。

我相信它仍然需要修改以引用 2.0 发布的二进制文件。 @weshaggard @mellinoe现在不受阻止吗? 你还有什么需要他做的事情来准备好在 hte metapackage 中发货吗?

@danmosemsft我们现在唯一等待的是将 corefx/master 重新命名为“preview1”而不是“preview2”。 如果我们现在发布一个版本,有一些与升级相关的丑陋之处,因为新版本的包(如果我们想发布它们)总是比名称中带有“preview2”的版本具有“更低”的版本。

标准 System.Drawing 实现的目标应该是尽快成为 SkiaSharp 库的包装器,原因如下:

  • 很快,许多 .Net 开发人员将开始使用它来开发 NetCore 跨平台应用程序的 GUI,如果性能不足,我们将结束对 Java Swing 灾难的重制。 缓慢而笨拙的 GUI 会使使用 NETCore 的跨平台开发变得不那么令人愉快,并且会对所有 NETCore 应用程序造成不利影响,就像 Swing 应用程序发生的那样,它们永远无法与本机应用程序竞争。
  • 我们不需要 System.Drawing 的托管实现是不正确的。 没有托管图形后端这样的东西。 当涉及到图形设备时,您必须在低级别工作。 指针、按位运算、内存分配和适合特定硬件架构的数据结构是必要的。 这就是旧的 System.Drawing 不容易移植的原因,因为它专门链接到 Windows 驱动程序和非托管 GDI 后端。
  • 低层次支持所有不同平台的工作是巨大的。 创建和维护许多不同的图形后端是浪费每个人的时间。 Skia 已经是一个跨平台的开放项目,在全球范围内有许多贡献者,并且多年来为数十个硬件平台和操作系统添加了用于低级别支持的特定代码。 SkiaSharp 作为 Skia 包装器,是 NetCore 在跨平台图形方面的权威解决方案,也是我们为实现真正的多平台持久和开放代码而必须维护的唯一解决方案。
  • 使 System.Drawing 的标准版本围绕 SkiaSharp 进行包装也将帮助开发人员在需要做更复杂的事情时,逐步学习如何直接使用 SkiaSharp。 基于仅为 System.Drawing 库制作的临时和特定图形后端的 System.Drawing 将使开发人员很难使用 System.Drawing 将其代码从原始代码发展或扩展到更多内容。 他们可能会最终坚持使用旧的、缓慢的原始代码,因为离开 System.Drawing 并立即为 SkiaSharp 重写所有代码的成本太高了。 底层的 SkiaSharp 后端将允许开发人员仅在需要改进直接调用 SkiaSharp 方法的代码的地方逐渐扩展他们的代码。
  • System.Drawing 将成为一个巨大的示例项目,可用于学习 SkiaSharp,这是 NETCore 开发人员需要学习的唯一跨平台图形库。

抱歉@Emasoft ,我不太同意这一点。 SkiaSharp 是一个很好的库,在它之上构建一个 System.Drawing 兼容层不会有任何本质上的错误。 但是,这种努力以及与之相关的成本与我们目前正在努力实现的目标不一致。 我们只是试图为拥有遗留资产的人们提供一个迁移故事,以进入 .NET Core 的新世界。 我们不希望它成为新的面向未来的现代图像处理库。

很快,许多 .Net 开发人员将开始使用它来开发 NetCore 跨平台应用程序的 GUI,如果性能不足,我们将结束对 Java Swing 灾难的重制。 缓慢而笨拙的 GUI 会使使用 NETCore 的跨平台开发变得不那么令人愉快,并且会对所有 NETCore 应用程序造成不利影响,就像 Swing 应用程序发生的那样,它们永远无法与本机应用程序竞争。

已经有多个 UI 框架在 .NET Core 上运行——它们都没有使用 System.Drawing,也不应该使用 System.Drawing。 在面向未来的库中使用 System.Drawing 将是一个非常愚蠢的决定。 就其本质而言,它运行缓慢且组织混乱,并且具有非常过时和过时的 API。 由于它是 Windows 组件 (GDI+) 上的半透明包装器,因此它的大部分表面区域本质上是不可移植的。 如果您正在构建一个新的、现代的、跨平台的 UI 堆栈,您确实应该构建在一个专为这种环境设计的库之上,而不是 GDI+。

我们不需要 System.Drawing 的托管实现是不正确的。 没有托管图形后端这样的东西。 当涉及到图形设备时,您必须在低级别工作。 指针、按位运算、内存分配和适合特定硬件架构的数据结构是必要的。 这就是旧的 System.Drawing 不容易移植的原因,因为它专门链接到 Windows 驱动程序和非托管 GDI 后端。

托管代码支持您提到的所有内容。 我们还将确保这些类型的事情可以使用 .NET 完成作为首要任务。 我不认为 System.Drawing 需要(或应该)成为这样一个库,但我相信这些东西可以用 .NET 构建。 与本机包装器相比,托管解决方案有很多优势; 我认为,如果我们不尽力使这些事情成为可能,那对我们来说就是失败。

低层次支持所有不同平台的工作是巨大的。 创建和维护许多不同的图形后端是浪费每个人的时间。 Skia 已经是一个跨平台的开放项目,在全球范围内有许多贡献者,并且多年来为数十个硬件平台和操作系统添加了用于低级别支持的特定代码。 SkiaSharp 作为 Skia 包装器,是 NetCore 在跨平台图形方面的权威解决方案,也是我们为实现真正的多平台持久和开放代码而必须维护的唯一解决方案。

是的,我想支持尽可能少的后端。 鉴于 libgidplus 后端已经主要是功能性的,这似乎是最初要走的路。 创建一个基于 SkiaSharp 的后端将构成创建一个全新的包装层; 还有很多工作要做。

使 System.Drawing 的标准版本围绕 SkiaSharp 进行包装也将帮助开发人员在需要做更复杂的事情时,逐步学习如何直接使用 SkiaSharp。

我明白你在说什么,我在一定程度上同意。 这就是为什么我考虑在 ImageSharp 而不是 libgdiplus 上编写包装层的原因。 如果我们正在考虑编写一个新的包装层,我仍然强烈建议我们使用 ImageSharp,因为引入另一个本机依赖项对 .NET Core 来说是错误的方向。

@mellinoe我完全同意你的立场; 然而@Emasoft确实暗示了用户将 System.Drawing 视为未来图形开发的合法/首选依赖项的有效担忧,因为它存在于 BCL 中。 历史表明,关于 API 的“不适用”的“适合目的”声明往往会引起用户的混淆和不确定(例如:NET FX System.Drawing 在 ASP.NET 中不推荐/我对 HttpListener 标记为“遗留”的挫败感在 .NET Core 中。传达此类声明(文档/博客)也涉及大量成本。我还怀疑未来关于 .NET Core 的介绍性书籍将选择涵盖 System.Drawing 以解决简单的图形场景,这将有效地进一步建立 API 并延长其生命周期。所以我认为我们需要一个更正式的策略来处理 BCL 中包含的组件,纯粹是为了向后兼容。也许将这些组件放在专用的“兼容性”命名空间中,以便预先调整预期,在代码级别下。

@clrjunkie

我认为我们需要一个更正式的策略来处理纯粹为了向后兼容而包含在 BCL 中的组件。

是的,这是我们团队长期以来一直在努力解决的问题,我认为这是我们仍在学习如何最好地管理的问题。 我们讨论了各种策略,但没有找到任何令人满意的。 在我们最近的版本中,许多过去的选项已被我们删除,因此我们更重要的是弄清楚如何正确地向这些内容发送消息。

你好,

一般来说,对于新代码,我会提倡直接使用 SkiaSharp 来解决这个线程中已经提出的许多论点。

为了将 System.Drawing 提供给 .NET Core,采用 libgdiplus 的优势在于它的摩擦非常低,将其打包并使其可用的工作已经存在,并且一些文本渲染的困难部分已经到位.

当前方法的一个胜利是 Windows 上的 System.Drawing 将消耗 Windows libgdiplus,这意味着那里的兼容性会很好。 不利的一面是,除非人们归档并提供良好的错误报告和补丁,否则 Unix 版本将无法与之匹配 - 它非常接近,但存在一些已知的差距和一些已知的差距,其中一些可能不会被广泛记录 - 稍后会出现病态文件问题。

对于那些关心性能的人来说,未来可以走的一条路是将 libgdiplus 中的 Cairo 的使用替换为 Skia,这根本不会影响托管代码,这将是透明的换出。

我不会像@mellinoe 那样批评 GDI+,我认为其中一些是用太宽的画笔绘制它,但这是正确的:

如果您正在构建一个新的、现代的、跨平台的 UI 堆栈,您确实应该构建在一个专为这种环境设计的库之上,而不是 GDI+。

确切地。 鉴于有一些 SkiaSharp 的口径,你应该改用它。 而这正是像 Avalonia 这样的项目所做的。 Google 会不断改进它,我们会保持它的新鲜度和时效性,它是世界上两个最常用的软件的基础。

有没有机会像 Microsoft.Win32.Registry 那样获得 netstandard 存根?

@FixBo你的意思是哪个存根? 在不受支持的平台上抛出 PlatformNotSupported 异常?

@FixBo你纠正我们通常会这样做,例如在这种情况下,引用它的代码可以加载到 UAP 上(即使不使用它)。 @FixBo你需要什么平台 - 什么场景?

@danmosemsft我正在将一组库移植到 netstandard。 其中某些部分依赖于绘图,例如文档导出/打印。 另一方面,文档生成/pdf 导出/数据访问可以在纯网络标准上工作。
现在我有三个选择:将目标更改为 netcore、拆分 dll、使用大量定义。

@FixBo你的问题是System.Drawing.Common 是针对 netcoreapp2.0 而不是 netstandard 的吗?

@qmfrederik正确。

@FixBo我认为计划是让 System.Drawing.Common 目标 netstandard 但@mellinoe可以确认。

@qmfrederik目前,它实际上依赖于 Color 结构中的一些私有状态,该状态在 netstandard2.0 中未公开可用,但在 .NET Core 2.0 中(私有)实现。 我们必须对代码进行一些结构性更改才能重新定位到 .NET Standard 2.0。 或许在我们稳扎稳打之后,值得研究一下。

System.Drawing.ColorTranslator(我想念 System.Drawing.ColorTranslator.FromHtml)在 net core 2.1 中可用吗?

@safern你能评论一下FromHtml吗?

我不能从 .NET Standard 项目使用https://www.nuget.org/packages/System.Drawing.Common
错误 NU1202:包 System.Drawing.Common 4.5.0-preview1-25718-03 与 netstandard2.0 (.NETStandard,Version=v2.0) 不兼容。 包 System.Drawing.Common 4.5.0-preview1-25718-03 支持:netcoreapp2.0 (.NETCoreApp,Version=v2.0)

您是否有任何计划使其与 .NET Standard 项目也兼容。 图书馆作者会很感激的。

我不能从 .NET Standard 项目使用https://www.nuget.org/packages/System.Drawing.Common
错误 NU1202:包 System.Drawing.Common 4.5.0-preview1-25718-03 与 netstandard2.0 (.NETStandard,Version=v2.0) 不兼容。 包 System.Drawing.Common 4.5.0-preview1-25718-03 支持:netcoreapp2.0 (.NETCoreApp,Version=v2.0)
您是否有任何计划使其与 .NET Standard 项目也兼容。 图书馆作者会很感激的。

@VahidN谢谢你提出这个问题。 我们创建了问题: https :

System.Drawing.ColorTranslator(我想念 System.Drawing.ColorTranslator.FromHtml)在 net core 2.1 中可用吗?

我将不得不看看为什么我们没有从一开始就移植它。 @jmroyb我会更新你的。

@mellinoe和其他人:这花了我相当多的时间,但我已经仔细阅读了每篇文章和这里的每一条评论。 在不考虑某些特定于实现的细节的情况下,我有一个问题被顺便提到但没有解决。

将此作为 .NET Core 的一部分提供有什么好处? 请不要误解我 - 我很欣赏 System.Drawing 作为阻止任何遗留代码库迁移到 .NET Core 的阻塞依赖项的重要性。 但是,为什么必须通过向实际的 .NET Core/Standard 规范和实现添加一个遗留的、已弃用的、高度特定于系统的库来解决这个问题? 换个说法:如何简单地提供一个 NuGet 包,通过上面讨论的一种或多种方式实现 System.Drawing在这些特定平台上不足以帮助这些无法访问所需资源的开发人员进行迁移更好/更现代的替代方案?

通过将其包含在 .NET Core 中,我们不仅致力于为 CoreFx 当前支持的平台提供解决方案,而且还严格限制 CoreFx 将来可以轻松移植到哪些平台。

讨论 Linux 和 Android 上的 SkiaSharp 支持有多棒,这一切都很好,但是当有人想将 CoreFx 移植到 SPARC 或什至只是 Skia 或 libgdiplus 或诸如此类不支持的一些陈旧的 ARM 变体时会发生什么? FreeBSD 怎么样? 或者另一个尚未开发的操作系统?

我完全赞成开发这个库,但我认为需要仔细考虑它的影响。 在 Windows 10 Creators Update 之前,我是作为一个顽固的 SWF 粉丝来回避 Silverlight、WPF 和 XAML 的,当时我终于接受了 UWP。 我非常感谢学习新工具包的微妙之处和细微差别的困难以及迁移到缺少依赖项的平台的困难。 但是向后弯腰支持 System.Drawing 会得到什么?

似乎这个讨论几乎偏离了关于在 CoreFx 上支持 SWF 的对话,并忽略了最初的目标:让使用 SD 的应用程序更容易迁移到 CoreFx。 如果您退后一步,或许重新评估这一点,我将不胜感激。 我确实感谢在这项工作中投入的时间和精力,但没有必要浪费它,只需将讨论的所有内容发布到单独的包的上下文中,而不是 .NET Core 的一部分就可以实现所有相同的目标。

现在问一个以前被问过但没有回答的不同问题:虽然 SD 绝对是 Windows 上遗留 .NET FX 应用程序的用户阻止他们迁移到 CoreFx 的主要障碍问题,但从中受益的项目的实际数量扩展到尚未使用 SD/GDI+ 的更好替代方案的非 Windows 平台,预计目前使用 SD 的组织有多少会迁移到 .NET Core?

@mqudsi我假设它是通过.NET Core

如果我清楚地理解您的担忧是通过将 System.Drawing 添加到 .NET Core 会很难将此平台扩展/移植到另一个框架,即使用不同库的平台,对吗?

如果这是您的担忧并且我理解正确,System.Drawing 既不是 .NET Core 中的收件箱,也不是 netstandard,这意味着它在 NuGet 中作为独立包提供,如果人们想使用它,他们只需在他们的项目中引用该包. 这样做是为了使从 .NET Framework 迁移到 .NET Core 更容易的兼容性工作。 因此,我们正在实现两个目标,即兼容性,并且我们不会将其添加为框架收件箱的一部分。 从我在您的评论中所理解的内容来看,这对于您的关注(这是合理的)也不会影响您。 如果这不是您主要关心的问题,请随时纠正我。

回答你的最后一个问题,.NET Core 的重点是为不同平台提供可移植性和可扩展性,如果开发人员有一个使用 System.Drawing 的 .NET Framework 应用程序,但他们不想移植它,因为他们没有得到太多因为它将仅支持 Windows(与他们当前的应用程序中的相同),与我们在 Unix 中也支持它相比,这项工作的品脱是什么,他们免费获得他们的应用程序的可移植性并且是一个很好的迁移到 .NET Core 的动机。

@mqudsi我假设它是通过 .NET Core 的 Windows 兼容包提供的,而不是 .NET Standard 的一部分

正确,也可以作为 NuGet 中的单独包。

谢谢! 这是我第二次进入 CoreFX 的 github 页面(第一次是我今天早些时候的 PR),并假设这里的问题意味着它是“核心”CoreFx 的一部分。

谢谢澄清!

回答你的最后一个问题,.NET Core 的重点是为不同平台提供可移植性和可扩展性,如果开发人员有一个使用 System.Drawing 的 .NET Framework 应用程序,但他们不想移植它,因为他们没有得到太多因为它将仅支持 Windows(与他们当前的应用程序中的相同),与我们在 Unix 中也支持它相比,这项工作的品脱是什么,他们免费获得他们的应用程序的可移植性并且是一个很好的迁移到 .NET Core 的动机。

我认为在 Unix 上提供 System.Drawing 支持将提供零动力转向 .NET Core

我认为在 Unix 上提供 System.Drawing 支持将提供零动力转向 .NET Core

.NET Core 上似乎有对 System.Drawing 的需求; CoreCompat.System.Drawing、CoreCompat.System.Drawing.v2 和 System.Drawing.Common 在 NuGet 上的下载量超过 300,000。

在某些情况下,“在所有平台上都付出了巨大的努力”:10 多年前,Mono 已将 System.Drawing 移植到 Linux 和 macOS。 他们还使 libgdiplus 与基于 ARM 的操作系统(如 Android 和 iOS)兼容。 CoreFX 正在做的是整合 System.Drawing 的 Windows、Linux 和 macOS 实现。

归根结底,这是另一个可供您使用的 NuGet 包,您可以自由使用任何满足您要求的图像库😄。

.NET Core 上似乎有对 System.Drawing 的需求; CoreCompat.System.Drawing、CoreCompat.System.Drawing.v2 和 System.Drawing.Common 在 NuGet 上的下载量超过 300,000。

现在 System.Drawing 不在 BCL 中(一件好事),我认为重要的是我们拥有新的基本(但质量)图像处理支持作为 BCL 的一部分,特别是对于不需要任何外部依赖的图像调整大小和旋转。

见这里: https :

@safern这个问题还有用吗? 我们已经遇到了跟踪标记兼容包稳定的问题。 如果我们想进一步跟踪合并 Windows 和 Unix 代码,那么提出一个更集中的新问题可能是有意义的。

同意。 我们可以关闭这个 issue。

我正在研究一种使用平台扩展将我们的应用程序迁移到网络核心的方法,并注意到 System.Drawing.ImageConverter 不存在于平台扩展中。 它会得到支持吗? 这是报告此类事情的最佳地点,还是我应该提出单独的问题或在其他地方报告?

@voltcode可能应该打开一个新问题; 用于跟踪,如果它不在Windows 兼容包中

@voltcode这将是一个新问题,但实际上它已经添加到https://github.com/dotnet/corefx/pull/33092 中,您可以对其进行跟踪。

之后 .NET Core 应该拥有 System.Drawing 命名空间中 System.Drawing.dll 中的所有内容 - 我刚刚检查过。

不使用 blazor Webassembly

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

v0l picture v0l  ·  3评论

omariom picture omariom  ·  3评论

aggieben picture aggieben  ·  3评论

GitAntoinee picture GitAntoinee  ·  3评论

bencz picture bencz  ·  3评论