2009-05-20 14 views
11

Chciałbym móc utworzyć prosty obraz PNG, np. O czerwonym kwadracie przy użyciu usługi sieciowej w języku C# do generowania obrazu, wywoływanej z elementu HTML <img src="myws.ashx?x=100>.Utwórz obraz PNG za pomocą usługi WWW C# HttpHandler

jakiś przykład HTML:

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

Czy jest ktoś, kto może sklecić prostego (pracy) klasy C# tylko zaczynaj? Kiedy jestem poza domem, jestem pewien, że mogę to skończyć, żeby zrobić to, co chcę.

  • Koniec gry jest stworzenie prostych czerwony/bursztynowy/zielony (RAG) wbudowanych markerów stanu dla danych napędzane stronie internetowej, która zawiera dane wydajności itp *
  • chciałbym go używać PNG jako Przewiduję korzystania przejrzystość w przyszłości *
  • ASP.NET 2.0 C# rozwiązanie proszę ... (I nie masz jeszcze pole produkcja 3.5)

Tia

rOZWIĄZANIE

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

czy można zrobić procedurę obsługi http, zwracając obraz? powiedzmy obraz bitmapowy lub bufor bajtowy [] do metody C# (kod za plikiem), skąd jest wywoływany? Przepraszam, jeśli brzmi to oszałamiająco, ale jestem nowy w obsłudze HTTP – zack

+0

@YP, zobacz akceptowaną odpowiedź ?? W przeciwnym razie nie rozumiem, co masz na myśli i szczerze mówiąc, nie wiedziałbym, jak to zrobić. Mój C# jest bleh! – Guy

+0

@guy Dzięki za opublikowanie rozwiązania - bardzo mi pomogło! –

Odpowiedz

20

sieci, zwłaszcza SOAP oczekiwać rzeczy jak koperty XML ze szczegółami połączenia w Byłbyś lepiej wyłączyć za pomocą HttpHandler..

coś takiego:

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

} 

Jest to bardzo szorstki oczywiście. Nazwałbyś go wtedy:

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

Tak Nie przeoczyłem bitów, jeśli przejdziesz do okna dialogowego Dodaj nowy element, utworzymy dla Ciebie HttpHandler, lub zatrzymaj kursor nad IHttpHandler i wybierz "Zaimplementuj ten interfejs". To coś takiego: public bool IsReusable {get {return true; }} – Lloyd

+0

Dzięki - mam! Także pomniejsza literówka na Response.ContentType i ImageFormat.Png Teraz wystarczy, że wyciągnę coś/coś ... – Guy

+1

Do buforowania Widziałem, jak wspominałeś, możesz użyć HttpRuntime.Cache, po prostu zrzuć bajt [] wracaj z pamięci MemoryStream. – Lloyd

3

usługa internetowa nie nadaje się do tego. Zwraca komunikat w określonym formacie, zazwyczaj SOAP, więc nie może być obrazem.

Zamiast tego należy użyć zwykłego formularza internetowego, w którym usuwa się wszystkie znaczniki z wyjątkiem dyrektywy @page. Użyj metody BinaryWrite, aby zapisać dane obrazu w strumieniu odpowiedzi.

Przykład: Usługi

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

Jedyną zmianą, jaką można w tym celu zrobić, to użycie ogólnej procedury obsługi (pliku .ashx). Nie ma potrzeby narzucania całej strony (.aspx). – Keltex

+0

Jest to w rzeczywistości możliwe za pośrednictwem usługi internetowej; Robię to za pomocą plików PDF. Kluczem jest zwrócenie go jako tablicy bajtów, odtworzenie go na drugim końcu, a następnie zapisanie go za pomocą odpowiedniego ContentType. –

+0

@Adam V: W takim przypadku korzystasz z usługi internetowej tylko jako strony głównej dla strony internetowej. Nie możesz użyć odpowiedzi bezpośrednio z serwisu internetowego, o co poprosił Guy. – Guffa

0

NIE można wydrukować obrazu z usługi WebService.

Sprawdź to: http://www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx

+0

To zależy od sposobu wyświetlenia usługi internetowej. Całkowicie możliwe jest zwrócenie binarnego (obrazu) za pomocą wieloczęściowego kodowania mime za pośrednictwem interfejsu API C#. Zostało zrobione. Zapoznaj się z tym na początek: http://en.wikipedia.org/wiki/MIME To nie jest strasznie trudne zadanie w C# – Demi

+1

"To zależy od tego, jak przeglądasz serwis internetowy." << Zgadzam się. – NinethSense

+0

Lub po prostu zwróć plik binarny, jak wspomniano w poście Guffa. :-) – Demi

0

Ponadto, w zależności od sposobu wdrożenia tego należy pamiętać, że może być ustawienie się na atak DOS. Generowanie obrazów nie jest najbardziej przyjazne procesorowi. Upewnij się, że masz mechanizm uwierzytelniania i/lub buforowania, aby pomóc złagodzić ten potencjalny punkt bólu.

+0

Jest to tylko do użytku wewnętrznego/intranetowego, ale buforowanie musi zostać wdrożone! Dzięki. – Guy

2

Myślę, że odpowiedź @ Lloyda to dobry początek.

miałem problemy z folii alfa i PNG: Can you make an alpha transparent PNG with C#?

+0

Ha! Studiuję twoje pytanie przez ostatnią godzinę.Jeśli uda mi się zdobyć trochę "prostych rzeczy", to jestem pewien, że mogę to zakończyć nawet dzięki mojej licznej znajomości języka C#. – Guy

1

istnieje inna droga do osiągnięcia służąc dynamicznego obrazu.

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

za realizację:

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

uruchomić usługę jako regularną usługę WCF i dodać usługę w app.config

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

można przekazać parametry aby uczynić go bardziej dynamiczny.

Powiązane problemy