使用 C# HttpHandler webservice 创建 PNG 图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/887985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create PNG image with C# HttpHandler webservice
提问by Guy
I'd like to be able to create a simple PNG image, say of a red square using a c# web based service to generate the image, called from an <img src="myws.ashx?x=100>
HTML element.
我希望能够创建一个简单的 PNG 图像,比如使用基于 ac# web 的服务生成图像的红色方块,从<img src="myws.ashx?x=100>
HTML 元素调用。
some example HTML:
一些示例 HTML:
<hmtl><body>
<img src="http://mysite.com/webservice/rectangle.ashx?size=100">
</body></html>
Is there is anyone who can cobble together a simple (working) C# class just to get me started? Once off and going I'm sure I can finish this off to actually do what I want it to do.
有没有人可以拼凑一个简单的(工作)C# 类来让我开始?一旦离开并开始,我相信我可以完成它来真正做我想要它做的事情。
- End game is to create simple Red/Amber/Green (RAG) embedded status markers for a data driven web page that shows performance metrics etc*
- I'd like it to use PNG's as I anticipate using transparency in the future*
- ASP.NET 2.0 C# solution please... (I don't have a production 3.5 box yet)
- 最终游戏是为显示性能指标等的数据驱动网页创建简单的红色/琥珀色/绿色 (RAG) 嵌入式状态标记*
- 我希望它使用 PNG,因为我预计将来会使用透明度*
- ASP.NET 2.0 C# 解决方案请...(我还没有生产 3.5 框)
tia
蒂亚
SOLUTION
解决方案
rectangle.html
矩形.html
<html>
<head></head>
<body>
<img src="rectangle.ashx" height="100" width="200">
</body>
</html>
rectangle.ashx
矩形.ashx
<%@ WebHandler Language="C#" Class="ImageHandler" %>
rectangle.cs
矩形.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;}
}
}
采纳答案by Lloyd
Web services, especially SOAP expect things like an XML envelope with the details of the call in. You'd be better off using a HttpHandler
.
Web 服务,尤其是 SOAP 需要诸如包含调用详细信息的 XML 信封之类的东西。最好使用HttpHandler
.
Something like this:
像这样的东西:
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();
}
}
}
}
This is very rough of course. You'd call it then:
这当然是非常粗糙的。你会这样称呼它:
<img src="myhandler.ashx?width=10&height=10"/>
回答by Guffa
A web service is not suitable for this. It returns a message in a specific format, typically SOAP, so it can't be an image.
Web 服务不适合于此。它以特定格式(通常是 SOAP)返回消息,因此它不能是图像。
Use a regular web form instead, where you remove all markup except the @page
directive. Use the BinaryWrite
method to write the image data to the response stream.
改用常规 Web 表单,在其中删除除@page
指令之外的所有标记。使用该BinaryWrite
方法将图像数据写入响应流。
Example:
例子:
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);
回答by NinethSense
It is NOT possible to output image from a WebService.
无法从 WebService 输出图像。
Check this: http://www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx
检查这个:http: //www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx
回答by Chad Ruppert
Also, depending on how you implement this, please be aware that you could be setting yourself up for a DOS attack. Generating images is not the most processor friendly thing. Please be sure to have some authentication and or caching mechanism in place to help alleviate this potential pain point.
此外,根据您如何实现这一点,请注意您可能正在为 DOS 攻击做好准备。生成图像并不是对处理器最友好的事情。请确保有一些身份验证和/或缓存机制来帮助缓解这个潜在的痛点。
回答by Keith
I think @Lloyd's answer is a good start.
我认为@Lloyd 的回答是一个好的开始。
I've had problems with alpha transparencies and PNGs: Can you make an alpha transparent PNG with C#?
我在使用 alpha 透明胶片和 PNG 时遇到了问题:你能用 C# 制作一个 alpha 透明的 PNG 吗?
回答by Jan Staal
There is another way to accomplish serving a dynamic image.
还有另一种方式来完成提供动态图像。
namespace MyApp
{
[ServiceContract]
public interface IMyService
{
[WebGet(UriTemplate = "Image.png")]
[OperationContract]
Stream ShowImage();
}
}
For the implementation:
对于实施:
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;
}
Start the service as a regular WCF service and add the service in your app.config
将该服务作为常规 WCF 服务启动并在您的 app.config 中添加该服务
(WebService = new WebServiceHost(typeof(MyService))).Open();
You can pass parameters to make it more dynamic.
您可以传递参数以使其更具动态性。