Frage

Ich brauche ein Bild dynamisch zu generieren, und nachdem ich gelesen das Tutorial hier ich weiß, ich alle Steuerelemente und Layouts von WPF können meine Rendering zu erzeugen, und speichern sie es dann als JPG. Die Idee ist, diese zu verwenden, anstatt GDI +, das ziemlich primitiv ist.

Die Frage ist, wie ich eine reguläre DLL-Datei erstellen, die so dann programmatisch eine WPF-Leinwand erzeugen würde ich Steuerelemente hinzufügen kann und dann ouput, dass auf eine Bilddatei. Beachten Sie, dass es von einer ASP.NET-Anwendung verbraucht werden würde.

Alle Ideen jemand?

War es hilfreich?

Lösung

Dieses Beispiel hat einen guten Start, aber ich gefunden habe es zusammen mit ihm eine Menge unnötigen Junk bekommt. Die Hauptsache ist, dass Sie keine separate WPF-Projekt haben müssen.

Hier ist was zu tun ist:

  • Referenz PresentationCore, PresentationFramework und Windows in Ihrem Web-Projekt.
  • Erstellen Sie eine Leinwand und anderen WPF-Objekte programmatisch in einem STA-Thread.
  • ein paar speziellen Methoden auf sich anrufen, um sie außerhalb des Kontexts einer WPF-Anwendung stellen Sie sicher, aktualisieren.
  • Render sie auf ein Bild mit Rendertargetbitmap.
  • Beenden des Threads Dispatcher nach unten.
  • Stellen Sie den MIME-Typ und gibt das Bild mit ASP.NET.

Um dies effizienter Sie könnten den gleichen Thread wieder verwenden, anstatt einen neuen für jedes Bild zu schaffen. In diesem Fall müssen Sie nur den Dispatcher bereinigen, wenn Sie den Thread geschlossen.

Hier ist der volle Arbeits Code, den ich habe:

using System;
using System.Web;
using System.Threading;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Documents;

public partial class _Default : System.Web.UI.Page
{
    private byte[] imageBuffer;

    public void Page_Load(object sender, EventArgs e)
    {
        this.RenderImage();

        Response.Clear();
        Response.ContentType = @"image/png";
        Response.BufferOutput = true;
        Response.BinaryWrite(this.imageBuffer);
        Response.Flush();
    }

    public void RenderImage()
    {
        Thread worker = new Thread(new ThreadStart(this.RenderImageWorker));
        worker.SetApartmentState(ApartmentState.STA);
        worker.Name = "RenderImageWorker";
        worker.Start();
        worker.Join();
    }

    public void RenderImageWorker()
    {
        Canvas imageCanvas = new Canvas { Width = 600, Height = 200, Background = Brushes.Azure };

        TextBlock tb = new TextBlock();
        tb.Width = (double)400;
        //tb.Height = (double)200;
        tb.TextAlignment = TextAlignment.Center;
        tb.Inlines.Add(new Run("This is "));
        tb.Inlines.Add(new Bold(new Run("bold")));
        tb.Inlines.Add(new Run(" text."));
        tb.FontSize = 30;
        tb.Foreground = Brushes.Blue;

        imageCanvas.Children.Add(tb);

        // Update layout
        imageCanvas.Measure(new Size(imageCanvas.Width, imageCanvas.Height));
        imageCanvas.Arrange(new Rect(new Size(imageCanvas.Width, imageCanvas.Height)));

        RenderTargetBitmap bitmapRenderer = new RenderTargetBitmap((int)imageCanvas.ActualWidth, (int)imageCanvas.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        bitmapRenderer.Render(imageCanvas);

        PngBitmapEncoder png = new PngBitmapEncoder();
        png.Frames.Add(BitmapFrame.Create(bitmapRenderer));

        using (MemoryStream memoryStream = new MemoryStream())
        {
            png.Save(memoryStream);
            this.imageBuffer = memoryStream.ToArray();
        }

        if (bitmapRenderer.Dispatcher.Thread.IsAlive)
        {
            bitmapRenderer.Dispatcher.InvokeShutdown();
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top