【问题标题】:Efficient image manipulation in C#C# 中的高效图像处理
【发布时间】:2010-10-29 14:59:09
【问题描述】:

我正在使用System.Drawing 类从用户上传的照片中生成缩略图和带水印的图像。上传原件后,用户还可以使用 jCrop 裁剪图像。我从其他人那里接手了这段代码,并希望对其进行简化和优化(它正被用于高流量的网站)。

前面的人有静态方法,接收位图作为参数并返回一个,内部分配和处置Graphics 对象。我的理解是Bitmap实例包含内存中的整个图像,而Graphics基本上是一个绘制操作队列,并且是幂等的。

目前流程如下:

  • 接收图像并将其存储在临时文件中。
  • 接收裁剪坐标。
  • 将原始位图加载到内存中。
  • 从原始位图创建一个新位图,应用裁剪。
  • 在新位图上做一些疯狂的亮度调整,也许(?)返回一个新位图(我不想碰这个;指针算法比比皆是!),我们称之为 A。
  • 从生成的位图创建另一个位图,应用水印(我们称之为 B1)
  • 从 A 创建一个 175x175 的缩略图位图。
  • 从 A 创建一个 45x45 的缩略图位图。

这似乎是很多内存分配;我的问题是:重写部分代码并重用Graphics 实例是否是一个好主意,实际上是创建一个管道?实际上,我只需要内存中的 1 张图像(原始上传),其余的可以直接写入磁盘。所有生成的图像都需要裁剪和亮度转换,以及该版本独有的单一转换,从而有效地创建操作树。

有什么想法或想法吗?

哦,我可能应该提一下,这是我第一次真正使用 .NET,所以如果我说的有些混乱,请耐心等待并给我一些提示。

【问题讨论】:

  • 很遗憾,这是您第一次与 .NET 交互。 IDisposable 模式是我对框架真正唯一持久的挫败感。这种“使用”业务是最深奥的常用功能 - 大多数事情都非常简单。
  • 好问题,我说! +1
  • 我不得不查找“幂等”...好词。
  • 发现您有性能问题?
  • +1 表示“疯狂的亮度调节”

标签: c# .net asp.net image


【解决方案1】:

重用 Graphics 对象可能不会带来显着的性能提升。

底层 GDI 代码简单地为您在 RAM(内存 DC)中加载的位图创建设备上下文。

您操作的瓶颈似乎是从磁盘加载图像。

为什么要从磁盘重新加载图像?如果它已经在 RAM 中的字节数组中,它应该在上传时存在 - 您可以在字节数组上创建一个内存流,然后从该内存流创建一个位图。

也就是说,将它保存到磁盘,但不要重新加载它,只需从 RAM 中对其进行操作即可。

此外,您不需要创建新的位图来应用水印(取决于它是如何完成的。)

您应该分析操作以查看需要改进的地方(或者即使需要改进)。

【讨论】:

    【解决方案2】:

    这个过程似乎是合理的。每个图像在保存到磁盘之前都必须存在于内存中——因此每个版本的缩略图都将首先存在于内存中。确保其有效工作的关键是 Dispose 您的 Graphics 和 Bitmap 对象。最简单的方法是使用 using 语句。

    using( Bitmap b = new Bitmap( 175, 175 ) )
    using( Graphics g = Graphics.FromBitmap( b ) )
    {
       ...
    }
    

    【讨论】:

    • 我真正的问题更像是:如果我重用 Graphics 对象,它会提高性能吗?
    【解决方案3】:

    我不久前完成了一个类似的项目,并进行了一些实际测试,看看如果我重用 Graphics 对象而不是为每个图像旋转一个新对象,性能是否会有所不同。就我而言,我正在处理大量图像的稳定流(“批次”中> 10,000)。我发现通过重用 Graphics 对象确实稍微提高了性能。

    我还发现,通过在 Graphics 对象中使用 GraphicsContainers 可以轻松地将不同的状态交换进/出对象,因为它用于执行各种操作,因此我得到了轻微的提升。 (具体来说,我必须在每张图像上应用裁剪并绘制一些文本和一个框(矩形)。)我不知道这对你需要做的事情是否有意义。您可能想查看 Graphics 对象中的 BeginContainer 和 EndContainer 方法。

    就我而言,差异很小。我不知道您是否会在实施中获得或多或少的改进。但是由于重写代码会产生成本,因此您可能需要考虑完成当前设计并在重写之前进行一些性能测试。只是一个想法。

    一些您可能会觉得有用的链接:

    Using Nested Graphics Containers
    GraphicsContainer Class

    【讨论】:

      【解决方案4】:

      我只是随便把它扔在那里,但如果你想要一个快速“指南”来了解处理图像的最佳实践,请查看 Paint.NET 项目。如需免费的高性能图像处理工具,请查看AForge.NET

      AForge 的好处是允许您执行很多这些步骤,而无需每次都创建新的位图。如果这是针对网站的,我几乎可以保证您正在使用的代码将成为应用程序的性能瓶颈。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-10
        • 2017-06-30
        • 1970-01-01
        • 1970-01-01
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 2013-09-07
        相关资源
        最近更新 更多