在ASP.NET C# Web应用程序中动态创建图像的正确方法是什么?

3

我对ASP.NET还比较陌生,但是我已经用C#开发了很多WinForms应用程序,在这些应用程序中,我广泛使用System.Drawing.Bitmap命名空间而没有遇到太多问题。

今天,我决定在我的Page_Load事件中编写一些代码来动态创建一些PNG文件,并且一切似乎都很正常。但是我注意到微软文档网站上出现了这个看起来很可怕的warning。这是怎么回事??

我不知道除了使用System.Drawing.Bitmap之外还有其他处理图像的方法... 我感到困惑:(


我自己在网站中使用过这个类,没有出现任何问题。很好能够看到对该问题的确认(我假设是线程安全或使用固定内存)。 - Oded
我只能赞同这里的其他人。我这里也没有应用程序崩溃或奇怪的行为报告。不过,这是一个有趣的问题。 - Pedery
System.Drawing在asp.net中运行良好。但是当我编写一个asp.net图像调整模块(http://imageresizingin.net)时,我发现了其他陷阱。我写了一篇关于它的文章:http://nathanaeljones.com/163/20-image-resizing-pitfalls/ - Lilith River
4个回答

3
你在Page_Load事件中描述了动态生成图像,这表明你的图像是由ASP.NET页面提供的。如果您不提供页面,则无需承担实例化页面对象及其关联对象、生命周期事件等性能开销。
更好或更适当的生成图像的方法是从较轻的HttpHandler中提供它们(但您仍然可以很好地使用Bitmap)。要实现IHttpHandler接口,您只需要实现2个方法,而且这没有太多难度。像这样实现:
<%@ WebHandler Language="C#" Class="ImageHandler" %>
using System;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

public class ImageHandler : IHttpHandler
{
    public void ProcessRequest (HttpContext context)
    {   
        Bitmap output = new Bitmap(path);

        // Do lots of fun stuff here related to image
        // manipulation and/or generation

        ...

        context.Response.ContentType = ResponseType("Image/png");

        // Send image to the browser
        image.Save(context.Response.OutputStream, ImageType(path));

        // Be careful to clean up; you could put this inside a 'using' block    
        image.Dispose();
    }

    public bool IsReusable
    {
        get { return true; }
    }
}

请注意:这不是有效的代码,只是一个小例子,让您了解一下。

将您的代码放在HttpHandler中,您就能更接近于完美。无论如何,它肯定会更快地提供您的图片,并允许您处理更多的请求...此外,您还可以学习更多的框架知识;-)


我应该补充一点,你需要使用 .ashx 文件扩展名来创建你的 HttpHandler,例如 ImageHandler.ashx。 - Scott

2
这个警告的原因是,Windows服务控制管理器(SCM)为每个服务(如ASP.NET)创建一个不可见的Windows站点(根据MS设计,不应具有UI元素),您可能会遇到像这样的错误,导致GDI +频繁调用Windows内核dll而崩溃。但正如你所看到的,微软再次作为服务提供商,在他们的角色中显得不够考虑周到和尊重用户,没有解释更多或至少将链接放在某个地方 = 人们很担心并且会变白头发。
我曾经收藏了一篇非常好的研究文章,但现在找不到了,很抱歉。
无论如何,我从未在使用该命名空间时遇到过大问题,所以不要担心,只要您明确地处置位图或在using() {}语句中处理它们即可。你得到我的99.9%保证(0.1%保留给我可能需要出席的任何法庭诉讼:)

0

我认为这是出于法律原因,作为“自行承担风险,不要因为您的Web服务器停机而责怪我们的库”的声明。

但是我之前在这样的环境中使用过它,并没有遇到任何问题。


0

GDI+在ASP.NET下大部分情况都能工作,尽管文档中有警告,但在重负载(100,000+图片)下可能会遇到问题,包括似乎无原因抛出异常,当您重试相同操作时,它却正常工作。

在这种情况下唯一的解决方法是运行独立的渲染进程,它们经常被回收,使用MSMQ与ASP.NET通信。对于低流量站点,我怀疑您不会遇到任何问题。

您确实需要正确丢弃位图,并避免使用Image.FromFile(),因为它存在问题。请参见http://blog.abodit.com/2010/07/gdi-image-fromfile-problem/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接