2009-05-20 34 views
11

Me gustaría poder crear una imagen PNG simple, digamos de un cuadrado rojo usando un servicio basado en C# web para generar la imagen, llamada desde un elemento HTML <img src="myws.ashx?x=100>.Crear imagen PNG con C# HttpHandler webservice

algún ejemplo HTML:

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

¿Hay alguien que puede improvisar una sencilla (de trabajo) C# clase sólo para ayudarme a empezar? Una vez apagado y listo estoy seguro de que puedo terminar esto para realmente hacer lo que quiero que haga.

  • juego final es crear/ámbar/verde (GAR) marcadores de estado sencillos rojos incrustados para una página web basada en los datos que muestra las métricas de rendimiento, etc *
  • me gustaría que utilice PNG como anticipo utilizando transparencia en el futuro *
  • ASP.NET 2.0 C# solución por favor ... (no tengo una caja de producción 3.5 todavía)

tia

sOLUCIÓN

rectangle.html

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

rectangle.ashx

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

rectangle.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;} 
    } 
} 
+0

¿Puede hacer que un manejador de http devuelva una imagen? digamos una imagen de mapa de bits o un búfer de bytes [] a un método C# (código detrás del archivo) desde donde se llama? Lo siento si sueno stupipd pero soy nuevo en http manejadores – zack

+0

@YP, ver la respuesta aceptada ?? De lo contrario, no entiendo lo que quieres decir y francamente, no sabría cómo hacerlo de todos modos. Mi C# es bleh! – Guy

+0

@guy Gracias por publicar la solución, ¡me ayudó mucho! –

Respuesta

20

Web, especialmente de SOAP esperar cosas como un sobre XML con los detalles de la llamada en Usted sería mejor usar un HttpHandler..

Algo como esto:

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(); 
      } 
     } 
    } 

} 

Esto es muy duro, por supuesto. Lo llamaría entonces:

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

Sí, omití bits, si entras en el cuadro de diálogo Agregar elemento nuevo, crearás un HttpHandler correctamente, o colocarás el cursor sobre IHttpHandler y seleccionar "Implementar esta interfaz". Es algo así como: public bool IsReusable {get {true; }} – Lloyd

+0

Gracias - ¡lo tengo! También error menor en Response.ContentType e ImageFormat.Png Ahora solo necesito que dibuje algo/lo que sea ... – Guy

+1

Para el almacenamiento en caché Te he visto mencionar que puedes usar HttpRuntime.Cache, solo volcar el byte [] regreso de MemoryStream allí. – Lloyd

3

Un servicio web no es adecuado para esto. Devuelve un mensaje en un formato específico, generalmente SOAP, por lo que no puede ser una imagen.

Utilice un formulario web normal en su lugar, donde se eliminan todas las marcas excepto la directiva @page. Use el método BinaryWrite para escribir los datos de imagen en la secuencia de respuesta.

Ejemplo: Servicios de

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); 
+0

El único cambio que le haría a esto es usar un controlador genérico (archivo .ashx). No hay necesidad de toda la página (.aspx) por encima. – Keltex

+0

En realidad es posible hacerlo a través de un servicio web; Lo hago con archivos PDF. La clave es devolverlo como una matriz de bytes, reconstituirlo en el otro extremo y luego escribirlo con el ContentType apropiado. –

+0

@ Adam V: Entonces solo está utilizando el servicio web como back-end para una página web. No puede usar la respuesta del servicio web directamente, como Guy solicitó. – Guffa

0

NO es posible emitir imágenes desde un servicio web.

Comprobar esto: http://www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx

+0

Esto depende de cómo se ve un servicio web. Es perfectamente posible devolver un binario (imagen) usando la codificación mime multiparte a través de una API web C#. Se ha hecho. Refiérase a esto para empezar: http://en.wikipedia.org/wiki/MIME Esto no es tan difícil de hacer en C# – Demi

+1

"Esto depende de cómo se ve un servicio web". << Estoy de acuerdo. – NinethSense

+0

O simplemente devuelve binario, como se menciona en la publicación de Guffa. :-) – Demi

0

También, dependiendo de cómo se implementa esto, por favor tenga en cuenta que usted podría estar preparando para un ataque DoS. Generar imágenes no es lo más amigable con el procesador. Asegúrese de tener algún mecanismo de autenticación y/o almacenamiento en caché para ayudar a aliviar este punto de dolor potencial.

+0

Solo para uso interno/Intranet, pero se deberá implementar el almacenamiento en caché. Gracias. – Guy

2

Creo que la respuesta de @ Lloyd es un buen comienzo.

he tenido problemas con transparencias alfa y PNG: Can you make an alpha transparent PNG with C#?

+0

¡Ja! Estuve estudiando tu pregunta durante la última hora.Si puedo obtener algunas de las "cosas simples" en ese momento, estoy seguro de que puedo terminar con mi conocimiento nudo C#. – Guy

1

Hay otra manera de lograr que sirve una imagen dinámica.

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

Para la ejecución:

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; 
} 

iniciar el servicio como un servicio regular de WCF y agregar el servicio en su app.config

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

Puede pasar parámetros para que sea más dinámica.