在DLL使用WPF创建图像动态(而不是GDI +) [英] Using WPF on a DLL to create Images Dynamically (instead of GDI+)

查看:171
本文介绍了在DLL使用WPF创建图像动态(而不是GDI +)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要动态生成图像,经过我阅读教程这里我意识到我可以使用所有控件和布局从WPF生成我的呈现,然后将其保存为JPG。
该想法是使用代替GDI +,这是相当原始此。

I need to generate an image dynamically, and after I read the tutorial here I realize i can use all the controls and layouts from WPF to generate my rendering, and then save it as a JPG. The idea is to use this instead of GDI+, which is quite primitive.

现在的问题是,如何创建,将产生一个编程WPF画布这样的话我就可以控件添加到它,然后输出中的一个图像文件常规DLL文件。请记住,它会通过一个ASP.NET应用程序被消耗掉。

The question is, how to I create a regular dll file that would generate programatically a WPF canvas so then i can add controls to it and then ouput that to an image file. Keep in mind that it would be consumed by an ASP.NET application.

任何想法别人?

推荐答案

这例子有一个良好的开端,但我发现它有很多不必要的垃圾随之。最主要的是,你不需要有一个单独的WPF项目。

That example has a good start but I've found it's got a lot of unneeded junk along with it. The main thing is that you don't need to have a separate WPF project.

下面是做什么:


  • 参考presentationCore,presentationFramework和WindowsBase在Web项目。

  • 创建一个画布和其他WPF在STA线程编程的对象。

  • 呼吁他们一些特殊的方法,以确保他们更新一个WPF应用程序的上下文之外。

  • 渲染它们与RenderTargetBitmap的图像。

  • 关闭线程的调度员。

  • 设置MIME类型和输出ASP.NET的形象。

为了使这个更有效,你可以重复使用相同的线程,而不是创建为每个图像一个新的。在这种情况下,你只需要清理分发程序,当你关闭线程。

To make this more efficient you could re-use the same thread rather than creating a new one for each image. In that case you would only need to clean up the dispatcher when you shut down the thread.

下面是完整的工作code我有:

Here's the full working code I have:

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

这篇关于在DLL使用WPF创建图像动态(而不是GDI +)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆