ASP.NET 在服务器端创建缩略图
使用 System.Drawing 在 ASP.NET 应用程序中创建缩略图看起来非常容易。但是 MSDN 告诉您:
不支持在 Windows 或 ASP.NET 服务中使用 System.Drawing 命名空间中的类。尝试在这些应用程序类型之一中使用这些类可能会产生意外的问题,例如服务性能下降和运行时异常。
我在这种类型的 GDI+ 代码中看到间歇性的“内存不足”错误。我开始怀疑这就是原因。
人们如何进行服务器端图像处理?任何人都可以推荐任何不会炸毁我的服务器的替代方案吗?
相关代码如下。该异常间歇性地发生在 System.Drawing.Graphics.DrawImage 中。我刚刚继承了这个项目,所以我需要检查日志以了解发生此问题的频率/我们获得异常的频率...
public byte[] Resize(int newWidth, int newHeight, Image orignalImage)
{
Bitmap bitmap = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
Rectangle r = new Rectangle(0, 0, newWidth, newHeight);
g.DrawImage(orignalImage, r, r.X, r.Y, orignalImage.Width, orignalImage.Height, GraphicsUnit.Pixel);
MemoryStream stream = new MemoryStream();
bitmap.Save(stream, ImageFormat.Jpeg);
// clean up memory leaks
if (bitmap != null)
{
bitmap.Dispose();
bitmap = null;
}
if (g != null)
{
g.Dispose();
g = null;
}
return stream.ToArray();
}
更新:我已经搜索过整个项目中我们使用 GDI+ 的任何地方,并将 using() { }
放在所有 IDisposable
周围。自从我这样做以来,我还没有见过任何“内存不足”的异常。
It look desceptively easy to use System.Drawing to create thumbnails in your ASP.NET application. But MSDN tells you:
Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.
I'm seeing intermittented 'out of memory' errors within this type of GDI+ code. I'm beginning to suspect this is the cause.
How ARE people doing server side image manipulation? Can anyone recommend any alternative that WON'T blow up my server?
The relevant code below. The exception intermittently happens in System.Drawing.Graphics.DrawImage. I've just inherited this project, so I'd need to check the logs to see how often this is being hit / how often we get an exception...
public byte[] Resize(int newWidth, int newHeight, Image orignalImage)
{
Bitmap bitmap = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
Rectangle r = new Rectangle(0, 0, newWidth, newHeight);
g.DrawImage(orignalImage, r, r.X, r.Y, orignalImage.Width, orignalImage.Height, GraphicsUnit.Pixel);
MemoryStream stream = new MemoryStream();
bitmap.Save(stream, ImageFormat.Jpeg);
// clean up memory leaks
if (bitmap != null)
{
bitmap.Dispose();
bitmap = null;
}
if (g != null)
{
g.Dispose();
g = null;
}
return stream.ToArray();
}
UPDATE: I've searched thru the whole project for anywhere we are using GDI+ and put using() { }
around everything that's IDisposable
. I haven't seen one 'out of memory' exception since I did this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
假设您将对每个请求执行“操作”,问题可能是
处理器密集型操作:图像操作,这可能需要时间。
如果您正在保存文件,它将导致磁盘问题。
您可以考虑使用HTTP 处理程序,
处置 System.Drawing 对象应优先考虑(使用(){} 语句)
异步页面可以在此处探索。
Assuming you will be doing "stuff" per request, the issues might be
Processor intensive operation: manipulation of images, which could take time.
In case you are saving the file, it will lead to disk issues.
You can consider using HTTP handlers,
Disposing System.Drawing objects should be a priority(using(){} statement )
Asynchronous Pages can be explored here.
为什么不设置一个通过 Web 服务公开的单独工作服务器。
Why don't you set up a separate work server that is exposed through a web service.
我建议您在这些操作周围放置一些异常处理代码,以便保证您可以处理 GDI+ 对象。关闭流的好习惯...尽管据我所知
MemoryStream
对象是托管的,因此在 GC 时应该关闭自身。I would recommend you put some exception handling code around these operations so that you're guaranteed to dispose of your GDI+ objects. Good practice to close your streams too ... although to my knowledge
MemoryStream
object is managed so should close itself when GC'd.