Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中高效的图像处理#_C#_.net_Asp.net_Image - Fatal编程技术网

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对于“疯狂的屁股亮度调整”,我真正的问题更像是:如果我重新使用
图形
对象,它会提高性能吗?