C# C语言中高效的图像处理#
我正在使用C# C语言中高效的图像处理#,c#,.net,asp.net,image,C#,.net,Asp.net,Image,我正在使用系统.Drawing类从用户上传的照片生成缩略图和水印图像。用户还可以在上传原始图像后使用jCrop裁剪图像。我已经从其他人那里接管了这段代码,并希望对其进行简化和优化(它正在一个高流量网站上使用) 前一个家伙有静态方法,接收位图作为参数,并返回一个参数,在内部分配和处理图形对象。我的理解是,Bitmap实例包含内存中的整个图像,而Graphics基本上是一个绘制操作队列,它是幂等的 目前的工作流程如下: 接收图像并将其存储在临时文件中 接收作物坐标 将原始位图加载到内存中 应用裁剪
系统.Drawing
类从用户上传的照片生成缩略图和水印图像。用户还可以在上传原始图像后使用jCrop裁剪图像。我已经从其他人那里接管了这段代码,并希望对其进行简化和优化(它正在一个高流量网站上使用)
前一个家伙有静态方法,接收位图作为参数,并返回一个参数,在内部分配和处理图形
对象。我的理解是,Bitmap
实例包含内存中的整个图像,而Graphics
基本上是一个绘制操作队列,它是幂等的
目前的工作流程如下:
- 接收图像并将其存储在临时文件中
- 接收作物坐标
- 将原始位图加载到内存中
- 应用裁剪,从原始位图创建新位图
- 在新位图上做一些疯狂的亮度调整,也许(?)返回一个新位图(我不想碰这个;指针算法比比皆是!),让我们称之为a
- 从生成的位图创建另一个位图,应用水印(我们称之为B1)
- 从a创建175x175缩略图位图
- 从中创建一个45x45缩略图位图
图形
实例,实际上创建一个管道,这是一个好主意吗?实际上,我在内存中只需要一个图像(原始上传),而其余的可以直接写入磁盘。所有生成的图像都需要裁剪和亮度转换,以及该版本特有的单个转换,从而有效地创建操作树
有什么想法吗
哦,我可能应该提到,这是我第一次真正使用.NET,所以如果我说的话有些混乱,请耐心听我说,并给我一些提示。这个过程似乎是合理的。每个图像在保存到磁盘之前都必须存在于内存中,因此每个版本的缩略图都将首先存在于内存中。确保有效工作的关键是处理图形和位图对象。最简单的方法是使用using语句
using( Bitmap b = new Bitmap( 175, 175 ) )
using( Graphics g = Graphics.FromBitmap( b ) )
{
...
}
我只是想随便说说,但是如果你想快速了解使用图像的最佳实践,可以看看Paint.NET项目。要获得用于图像处理的免费高性能工具,请参阅
AForge的好处是允许您在每次不创建新位图的情况下执行这些步骤。如果这是针对一个网站,我几乎可以保证您使用的代码将成为应用程序的性能瓶颈 我不久前完成了一个类似的项目,并做了一些实际测试,看看如果我重用图形对象,而不是为每个图像旋转一个新对象,性能是否会有所不同。在我的例子中,我正在处理大量稳定的图像流(“批量”)中超过10000张图像。我发现通过重用图形对象,我的性能确实略有提高 我还发现,通过在图形对象中使用GraphicsContainers,可以轻松地将不同的状态切换到对象中/从对象中切换出来,因为它被用来执行各种操作,从而使我得到了一点提高。(具体地说,我必须应用裁剪并在每个图像上绘制一些文本和一个方框(矩形)),我不知道这对于您需要做的事情是否有意义。您可能希望查看图形对象中的BeginContainer和EndContainer方法 就我而言,差别很小。我不知道您的实现是否会得到或多或少的改进。但是,由于改写代码需要付出代价,所以您可能需要考虑在重写之前完成当前的设计并进行一些PARF测试。只是一个想法 您可能会发现一些有用的链接:
重用图形对象可能不会带来显著的性能提升 基础GDI代码simple为加载到RAM(内存DC)中的位图创建设备上下文 操作的瓶颈似乎是从磁盘加载映像 为什么要从磁盘重新加载映像?如果它已经在RAM中的字节数组中(上传时应该是这样),您可以在字节数组上创建一个内存流,然后从该内存流创建一个位图 换句话说,将其保存到磁盘,但不要重新加载,只需从RAM对其进行操作 此外,您不需要创建新位图来应用水印(取决于水印的使用方式)
您应该对操作进行分析,以了解它在哪些方面需要改进(甚至需要改进)。不幸的是,这是您第一次与.NET交互。IDisposable模式是我对框架真正唯一持久的失望。这种“使用”业务是最深奥的常用功能——大多数事情都非常简单。我说,好问题+1我必须查找“幂等元”。。。说得好。你发现性能问题了吗?+1对于“疯狂的屁股亮度调整”,我真正的问题更像是:如果我重新使用
图形对象,它会提高性能吗?