簡體   English   中英

以編程方式在控制台應用程序中即時創建和導出WPF Viewport3D可視對象

[英]Programmatically create and export WPF Viewport3D visual object in a console application on the fly

我正在使用Viewport3D的wpf用戶控件庫中開發wpf用戶控件。

我在運行的應用程序上在視口中看到該圖像,如果在WPF應用程序中調用它,則可以使用RenderTargetBitmap將其保存到文件中。

但是,如果我在控制台應用程序中實例化用戶控件並嘗試導出,則將保存空圖像。 該代碼是

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(DoIt);
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
        Console.WriteLine("press enter");
        Console.ReadLine();
    }
    static void DoIt()
    {
        var x = new WpfControlLibrary1.Showcase();

        x.GenerateViewPort();
        x.TakeScreenshot(300, 300);
    }
}

public partial class Showcase : UserControl
{
    private PerspectiveCamera _PerspectiveCamera = null;

    public Showcase()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler((sender, e) => this.GenerateViewPort());
    }

    public void GenerateViewPort()
    {
        this._PerspectiveCamera = new PerspectiveCamera(new Point3D(0, 0, 5), new Vector3D(0, 0, -5), new Vector3D(0, 1, 0), 45);

        var viewport3D = new Viewport3D() { Camera = this._PerspectiveCamera };
        viewport3D.Children.Add(new ModelVisual3D() { Content = GenerateModel() });
        viewport3D.Loaded += new RoutedEventHandler(this.viewport3D_Loaded);
        this.grdAniContainer.Children.Add(viewport3D);
    }

    private static Model3DGroup GenerateModel()
    {
        ...
    }

    void viewport3D_Loaded(object sender, RoutedEventArgs e)
    {
        ...
    }

    public void TakeScreenshot(int width, int height)
    {
        takeScreenshot(this.grdAniContainer.Children[0], width, height);
    }

    private static void takeScreenshot(Visual visual, int width, int height)
    {
        var v = visual as Viewport3D;
        v.Width = width;
        v.Height = height;
        v.Measure(new Size(width, height));
        v.Arrange(new Rect(0, 0, width, height));


        var vRect = new Rectangle();
        vRect.Width = width;
        vRect.Height = height;
        vRect.Fill = Brushes.White;
        vRect.Arrange(new Rect(0, 0, vRect.Width, vRect.Height));

        var bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
        bmp.Render(vRect);
        bmp.Render(v);

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

        var dlg = new SaveFileDialog();
        dlg.DefaultExt = ".png";
        dlg.Filter = "PNG Images (.png)|*.png";
        if (dlg.ShowDialog() ?? false == true)
        {
            string filepath = dlg.FileName;
            using (var stm = File.Create(filepath))
                png.Save(stm);
        }
    }

}

不會觸發Load事件,並且在控制台應用程序中未處理viewport3D_Loaded,因此我手動調用。

有沒有辦法將視覺效果加載到內存中並以編程方式渲染到文件?

我需要在“ takeScreenshot”方法中實例化“ bmp”后添加此委托

v.Dispatcher.Invoke(((Action)(() => bmp.Render(v))), DispatcherPriority.Render);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM