C#中的高效图像处理

Dan*_*eck 11 .net c# asp.net image

我正在使用这些System.Drawing类从用户上传的照片生成缩略图和水印图像.用户还可以在上传原件后使用jCrop裁剪图像.我从其他人手中接过了这个代码,我正在寻求简化和优化它(它在高流量网站上使用).

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

该过程目前的工作原理如下:

  • 接收图像并将其存储在临时文件中.
  • 接收裁剪坐标.
  • 将原始位图加载到内存中.
  • 应用裁剪,从原始位图创建新位图.
  • 做一些疯狂的亮度调整新的位图,也许(?)返回一个新的位图(我宁愿不触摸这个;指针算术丰富!),让我们称之为A.
  • 从结果中创建另一个位图,应用水印(让我们称之为B1)
  • 从A创建一个175x175缩略图位图.
  • 从A创建一个45x45缩略图位图.

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

任何想法或想法?

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

小智 3

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

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

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

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

换句话说,将其保存到磁盘,但不重新加载它,只是从 RAM 中对其进行操作。

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

您应该对操作进行概要分析,以了解哪里需要改进(或者即使需要改进)。