【问题标题】:Create PNG image with C# HttpHandler webservice使用 C# HttpHandler webservice 创建 PNG 图像
【发布时间】:2010-10-27 15:25:31
【问题描述】:

我希望能够创建一个简单的 PNG 图像,例如使用基于 c# Web 的服务生成图像的红色方块,从<img src="myws.ashx?x=100> HTML 元素调用。

一些示例 HTML:

<hmtl><body>
     <img src="http://mysite.com/webservice/rectangle.ashx?size=100">
</body></html>

有没有人可以拼凑一个简单的(工作的)C# 类来帮助我入门?一旦出发,我确信我可以完成这件事,真正做我想做的事。

  • 最终目标是为显示性能指标等的数据驱动网页创建简单的红色/琥珀色/绿色 (RAG) 嵌入式状态标记*
  • 我希望它使用 PNG,因为我预计将来会使用透明度*
  • 请提供 ASP.NET 2.0 C# 解决方案...(我还没有生产 3.5 的机器)

tia

解决方案

矩形.html

<html>
<head></head>
<body>
    <img src="rectangle.ashx" height="100" width="200">
</body>
</html>

矩形.ashx

<%@ WebHandler Language="C#" Class="ImageHandler" %>

矩形.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

public class ImageHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        int width = 600; //int.Parse(context.Request.QueryString["width"]);
        int height = 400; //int.Parse(context.Request.QueryString["height"]);

        Bitmap bitmap = new Bitmap(width,height);

        Graphics g = Graphics.FromImage( (Image) bitmap );
        g.FillRectangle( Brushes.Red, 0f, 0f, bitmap.Width, bitmap.Height );    // fill the entire bitmap with a red rectangle

        MemoryStream mem = new MemoryStream();
        bitmap.Save(mem,ImageFormat.Png);

        byte[] buffer = mem.ToArray();

        context.Response.ContentType = "image/png";
        context.Response.BinaryWrite(buffer);
        context.Response.Flush();
    }

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

【问题讨论】:

  • 你能让一个http处理程序返回一个图像吗?让我们说一个位图图像或一个字节 [] 缓冲区到一个 c# 方法(代码隐藏文件)从它被调用的地方?如果我听起来很愚蠢,我很抱歉,但我是 http 处理程序的新手
  • @YP,看到接受的答案了吗??否则我不明白你的意思,坦率地说,我也不知道该怎么做。我的 c# 是 bleh!
  • @guy 感谢您发布解决方案 - 帮了我很多!

标签: c# web-services png httphandler image


【解决方案1】:

Web 服务,尤其是 SOAP 期望诸如包含调用详细信息的 XML 信封之类的东西。最好使用 HttpHandler

类似这样的:

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

public class ImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        int width = int.Parse(context.Request.QueryString["width"]);
        int height = int.Parse(context.Request.QueryString["height"]);

        using (Bitmap bitmap = new Bitmap(width,height)) {

            ...

            using (MemoryStream mem = new MemoryStream()) {
                bitmap.Save(mem,ImageFormat.Png);
                mem.Seek(0,SeekOrigin.Begin);

                context.Response.ContentType = "image/png";

                mem.CopyTo(context.Response.OutputStream,4096);
                context.Response.Flush();
            }
        }
    }

}

当然,这很粗糙。你会这样称呼它:

<img src="myhandler.ashx?width=10&height=10"/>

【讨论】:

  • 是的,我错过了一些内容,如果您进入“添加新项目”对话框,将为您正确创建一个 HttpHandler,或者将鼠标悬停在 IHttpHandler 上并选择“实现此接口”。类似于: public bool IsReusable { get { return true; } }
  • 谢谢 - 明白了! Response.ContentType 和 ImageFormat.Png 上的小错字现在只需要让它绘制一些东西/任何东西......
  • 对于缓存,我看到你提到你可以使用 HttpRuntime.Cache,只需将来自 MemoryStream 的 byte[] 返回转储到那里。
  • 终于搞定了!使用 context.Response.BinaryWrite(buffer);劳埃德,如果你能纠正你答案中的错别字,那么你就得到了分数!!!
  • @Lloyd:你能让 http 处理程序返回图像吗?让我们说一个位图图像或一个字节 [] 缓冲区到一个 c# 方法(代码隐藏文件)从它被调用的地方?如果我听起来很愚蠢,我很抱歉,但我是 http 处理程序的新手
【解决方案2】:

Web 服务不适合这种情况。它返回特定格式的消息,通常是 SOAP,因此它不能是图像。

改用常规的网络表单,您可以在其中删除除@page 指令之外的所有标记。使用BinaryWrite方法将图片数据写入响应流。

例子:

byte[] imageData;
using (Bitmap image = new Bitmap(10,10)) {
   using (Graphics g = Graphics.FromImage(image)) {
      g.Clear(Color.Red);
   }
   using (MemoryStream m = new MemoryStream()) {
      image.Save(m, ImageFormat.Png);
      imageData = m.ToArray();
   }
}
Response.ContentType = "image/png";
Response.BinaryWrite(imageData);

【讨论】:

  • 对此我要做的唯一更改是使用通用处理程序(.ashx 文件)。不需要所有页面 (.aspx) 开销。
  • 实际上可以通过网络服务做到这一点;我用PDF来做。关键是把它作为一个字节数组返回,在另一端重构它,然后用适当的 ContentType 写出来。
  • @Adam V:那么您只是将 Web 服务用作网页的后端。正如 Guy 所要求的,您不能直接使用来自 Web 服务的响应。
【解决方案3】:

我认为@Lloyd 的回答是一个好的开始。

我在使用 alpha 透明度和 PNG 时遇到了问题:Can you make an alpha transparent PNG with C#?

【讨论】:

  • 哈!过去一个小时我一直在研究你的问题。如果我能正确地得到一些“简单的东西”,那么我相信即使我拥有丰富的 C# 知识,我也能完成它。
【解决方案4】:

还有另一种方法可以提供动态图像。

namespace MyApp
{
    [ServiceContract]
    public interface IMyService
    {
        [WebGet(UriTemplate = "Image.png")]
        [OperationContract]
        Stream ShowImage();
    }
}

对于实施:

public Stream ShowImage()
{
    Bitmap image = new Bitmap(@"C:\Image.png");
    Image image2 = new Bitmap(125, 125);

    using (Graphics graphics = Graphics.FromImage(image2))
    {
           graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
           graphics.SmoothingMode = SmoothingMode.HighQuality;
           graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
           graphics.CompositingQuality = CompositingQuality.HighQuality;
           graphics.DrawImage(image, 0, 0, 125, 125);
    }

    MemoryStream imageAsMemoryStream = new MemoryStream();
    image2.Save(imageAsMemoryStream, ImageFormat.Png);
    imageAsMemoryStream.Position = 0;
    return imageAsMemoryStream;
}

将该服务作为常规 WCF 服务启动并在您的 app.config 中添加该服务

(WebService = new WebServiceHost(typeof(MyService))).Open();

您可以传递参数使其更具动态性。

【讨论】:

    【解决方案5】:

    【讨论】:

    • 这取决于人们如何看待 Web 服务。完全可以通过 C# Web API 使用多部分 mime 编码返回二进制(图像)。它已经完成。初学者请参考:en.wikipedia.org/wiki/MIME 这在 C# 中并不是很有挑战性
    • "这取决于人们如何看待 Web 服务。"
    • 或者只返回二进制文件,如 Guffa 的帖子中所述。 :-)
    • 抱歉,我的术语可能有误(或者对于技术社区来说不够准确)我认为 .asmx 是返回 xml 内容?我以前没听说过 ashx。
    • @Guy,asmx 是 web 服务,ashx 是处理程序。 Ashx 与 aspx 几乎相同。它实现了 IHttpHandler。检查此以获取更多详细信息:stackoverflow.com/questions/619697/…。它可以帮助您生成图像。
    【解决方案6】:

    另外,根据您的实施方式,请注意您可能正在为自己设置 DOS 攻击。生成图像并不是对处理器最友好的事情。请确保有一些身份验证和/或缓存机制来帮助缓解这个潜在的痛点。

    【讨论】:

    • 仅供内部/内网使用,但必须实现缓存!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-12
    • 2013-09-13
    • 2010-10-28
    • 2017-07-30
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多