不能。
你写段用 VTK 在屏幕上绘图的代码我看看。
这是Winform的
using System.Drawing; using System.ServiceModel; using System; using System.Windows.Forms; using Kitware.VTK; using JXDWNav; using LungCare.WcfServices.Service.Interface; using System.Diagnostics; using System.Text; using System.IO; namespace CameraCorrectionService { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public partial class AirwayNav3DMapTestForm : Form, IAirwayNav3DMap { private const string WinstateTxt = "./winState.txt"; private const string TempVTP = "./temp.vtp"; private readonly int _splitContainer1Panel1Height; public AirwayNav3DMapTestForm() { InitializeComponent(); _splitContainer1Panel1Height = splitContainer1.Panel1.Height; splitContainer1.Panel1Collapsed = true; } public vtkRenderer Renderer { get { return _renderer; } } public vtkRenderWindowInteractor RenderWindowInteractor { get { return _iren; } } private XmlPolyDataPackage _airwayOn3DMap; private LinePackage _cameraPackage; private vtkRenderer _renderer; private vtkRenderWindow _renwin; private vtkRenderWindowInteractor _iren; private vtkInteractorStyleTrackballCamera _interactorStyle; internal vtkRenderer AddTopmostRenderer(vtkRenderWindow renwin, vtkRenderer mainRenderer) { int oldNumberOfRenderer = renwin.GetNumberOfLayers(); int newNumberOfRenderer = oldNumberOfRenderer + 1; mainRenderer.SetLayer(oldNumberOfRenderer - 1); vtkRenderer topRenderer = vtkRenderer.New(); topRenderer.SetViewport(0, 0, 1, 1); topRenderer.SetLayer(oldNumberOfRenderer); topRenderer.InteractiveOff(); renwin.SetNumberOfLayers(newNumberOfRenderer); renwin.AddRenderer(topRenderer); topRenderer.SetActiveCamera(mainRenderer.GetActiveCamera()); return topRenderer; } private void Airway3DMapPackageTestForm_Load(object sender, EventArgs e) { if (File.Exists(WinstateTxt)) { string[] lines = File.ReadAllLines(WinstateTxt); int x = int.Parse(lines[0]); int y = int.Parse(lines[1]); int w = int.Parse(lines[2]); int h = int.Parse(lines[3]); if (x > 0 && y > 0) { Location = new Point(x, y); } if (w > 120 && h > 120) { Width = w; Height = h; } } LocationChanged += AirwayNavVirtualEndoscopyTestForm_LocationChanged; Resize += AirwayNavVirtualEndoscopyTestForm_LocationChanged; _renwin = vtkRenderWindow.New(); _renderer = vtkRenderer.New(); _renwin.AddRenderer(_renderer); _renwin.SetParentId(panel1.Handle); _renwin.SetSize(panel1.Width, panel1.Height); _iren = vtkRenderWindowInteractor.New(); _iren.SetRenderWindow(_renwin); _interactorStyle = vtkInteractorStyleTrackballCamera.New(); _iren.SetInteractorStyle(_interactorStyle); _iren.ModifiedEvt += _iren_MouseMoveEvt; _iren.KeyPressEvt += delegate { string keysym = _iren.GetKeySym(); if (keysym == "Escape") { WindowState = FormWindowState.Minimized; } }; panel1.Resize += panel1_Resize; // 3D airway. // Set as non-topmost. string airwayVTPFileName = @".\data\girl.vtp"; if (File.Exists(TempVTP)) { airwayVTPFileName = TempVTP; } _airwayOn3DMap = new XmlPolyDataPackage(airwayVTPFileName, _renderer); vtkRenderer topmost = AddTopmostRenderer(_renwin, _renderer); _cameraPackage = new LinePackage(topmost); _cameraPackage.SetColor(1, 0, 0); // Parallel off. _renderer.GetActiveCamera().ParallelProjectionOn(); // Gradient on. _renderer.GradientBackgroundOn(); _renderer.SetBackground(0, 0, 0); _renderer.SetBackground2(0, 0, 1); _renderer.SetGradientBackground(true); _renderer.GetActiveCamera().OrthogonalizeViewUp(); _renwin.Render(); 正面观(); _orientationPackage = new OrientationPackage( vtpFile: @".\data\girl.vtp", renwin: _renwin, mainRenderer: _renderer); _renderer.ResetCameraClippingRange(); _renderer.ResetCamera(); } public void 正面观() { vtkCamera camera = _renderer.GetActiveCamera(); double[] bound = _airwayOn3DMap.GetBounds; camera.SetFocalPoint( (bound[0] + bound[1]) / 2, (bound[2] + bound[3]) / 2, (bound[4] + bound[5]) / 2); camera.SetPosition( (bound[0] + bound[1]) / 2, 1000, (bound[4] + bound[5]) / 2); camera.SetViewUp(0, 0, -1); } void panel1_Resize(object sender, EventArgs e) { _renwin.SetSize(panel1.Width, panel1.Height); _renderer.ResetCameraClippingRange(); //_renderer.ResetCamera(); _renwin.Render(); } internal void FlyTo(double[] focal) { double[] directionOfProjection = _renderer.GetActiveCamera().GetDirectionOfProjection(); double distance = _renderer.GetActiveCamera().GetDistance(); _renderer.GetActiveCamera().SetFocalPoint(focal[0], focal[1], focal[2]); _renderer.GetActiveCamera().SetPosition( focal[0] - distance * directionOfProjection[0], focal[1] - distance * directionOfProjection[1], focal[2] - distance * directionOfProjection[2]); } private bool _isProcessing = false; private OrientationPackage _orientationPackage; public void UpdateCamera(double[] cameraposition, double[] focalposition, double[] viewUp) { if (_isProcessing) { return; } _isProcessing = true; //vtkCamera camera = _renderer.GetActiveCamera(); //camera.SetPosition(cameraposition[0], cameraposition[1], cameraposition[2]); //camera.SetFocalPoint(focalposition[0], focalposition[1], focalposition[2]); //if (viewUp != null) //{ // camera.SetViewUp(viewUp[0], viewUp[1], viewUp[2]); //} _cameraPackage.SetPosition(cameraposition, focalposition); if (cbFly2Camera.Checked) { FlyTo(focalposition); } _renderer.ResetCameraClippingRange(); _renwin.Render(); _isProcessing = false; } private void AirwayNavVirtualEndoscopyTestForm_FormClosed(object sender, FormClosedEventArgs e) { Process.GetCurrentProcess().Kill(); } private void AirwayNavVirtualEndoscopyTestForm_LocationChanged(object sender, EventArgs e) { StringBuilder sb = new StringBuilder(); sb.AppendLine(Convert.ToString(Location.X)); sb.AppendLine(Convert.ToString(Location.Y)); sb.AppendLine(Convert.ToString(Width)); sb.AppendLine(Convert.ToString(Height)); File.WriteAllText(WinstateTxt, sb.ToString()); } private void panel2_MouseLeave(object sender, EventArgs e) { if (!cb自动隐藏.Checked) { return; } if (!Bounds.Contains(Cursor.Position)) { //panel1.Resize -= panel1_Resize; splitContainer1.Panel1Collapsed = true; //panel1.Resize += panel1_Resize; } } private void panel1_MouseMove(object sender, MouseEventArgs e) { //splitContainer1.Panel1Collapsed = false; } private void AirwayNavVirtualEndoscopyTestForm_MouseMove(object sender, MouseEventArgs e) { //splitContainer1.Panel1Collapsed = false; } void _iren_MouseMoveEvt(vtkObject sender, vtkObjectEventArgs e) { if (!cb自动隐藏.Checked) { return; } int[] position = _iren.GetEventPosition(); //Console.WriteLine(position[0] + @", " + position[1]); //panel1.Resize -= panel1_Resize; if (position[1] > Height - _splitContainer1Panel1Height) { splitContainer1.Panel1Collapsed = false; } else { splitContainer1.Panel1Collapsed = true; } //panel1.Resize += panel1_Resize; } public void Init(byte[] vtpFileBinaryData) { _airwayOn3DMap.PrintActor(); File.WriteAllBytes(TempVTP, vtpFileBinaryData); _airwayOn3DMap.ChangeFile(TempVTP); ResetCamera(); //File.Delete(_tempVTP); } private void ResetCamera() { _renderer.ResetCameraClippingRange(); _renderer.ResetCamera( _airwayOn3DMap.GetBounds[0], _airwayOn3DMap.GetBounds[1], _airwayOn3DMap.GetBounds[2], _airwayOn3DMap.GetBounds[3], _airwayOn3DMap.GetBounds[4], _airwayOn3DMap.GetBounds[5]); //_renderer.ResetCameraClippingRange(); //_renderer.ResetCamera(); _renwin.Render(); } private void btnColor_Click(object sender, EventArgs e) { ColorDialog colorDialog = new ColorDialog(); if (colorDialog.ShowDialog() == DialogResult.OK) { btnColor.BackColor = colorDialog.Color; _airwayOn3DMap.SetColor(colorDialog.Color); _renwin.Render(); } } private void tbOpacity_Scroll(object sender, EventArgs e) { _airwayOn3DMap.SetOpacity(tbOpacity.Value / 100.0); _renwin.Render(); } public bool HeartBeat() { return true; } public bool VisibiltyOff() { this.WindowState = FormWindowState.Minimized; //Visible = false; return true; } public bool VisibiltyOn() { this.WindowState = FormWindowState.Normal; //Visible = true; return true; } } }
@溪山行旅丶: 在 WPF 中可以用 VTK 绘制在 BMP 上。
@Launcher: 怎么获得wpf控件的句柄呢
@溪山行旅丶: 不用获得,而且也没有,WPF 只有一个 HWND 对象,使用 DirectUI 技术,所有其它控件都是采用的虚拟窗体,最后绘制在同一个 HWND 上的。你从 FrameworkElement 派生一个控件,添加一个 WriteableBitmap 类型的成员变量,然后重载 OnRender 方法,在此方法中使用 DrawingContext 的 DrawImage 将 WriteableBitmap 绘制到界面上。你的 VTK 相关的绘制都需要绘制到此 WriteableBitmap 上。而至于鼠标、键盘事件,你可能需要做些适配器来融合 WPF 的事件路由机制。
@Launcher: 受教了