2013-08-23 112 views
0

下面是一個簡單應用程序的代碼,該應用程序在窗口中的畫布上繪製矩形,然後在按任意鍵時使用CopyFromScreen函數拍攝應用程序的屏幕截圖。但在此之前,我稱之爲canvas.Children.Clear()。然後我會期望得到的圖像沒有矩形,但它確實。看起來,實際的矩形圖像並沒有在調用該函數時從畫布上移除,而是在一段時間之後。我試着把一個System.Threading.Thread.Sleep(1000);放在一個System.Threading.Thread.Sleep(1000)。在Clear()調用之後,矩形仍停留在屏幕上整整一秒。很明顯,在按鍵功能完成後它會被刪除,有沒有辦法在CopyFromScreen調用之前刪除它?清除畫布有延遲

要運行此操作,您需要添加對System.Drawing的引用。

XAML代碼

<Window x:Class="CanvasTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Width="210" Height="240" 
     KeyDown="keyPressed"> 
    <Window.Background> 
     <SolidColorBrush Color="White"/> 
    </Window.Background> 
    <Grid> 
     <Canvas Name="canvas" 
      HorizontalAlignment="Left" VerticalAlignment="Top"> 
     </Canvas> 
    </Grid> 
</Window> 

的.cs代碼

using System; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Shapes; 

namespace CanvasTest { 
    public partial class MainWindow : Window { 
     public MainWindow() { 
      InitializeComponent(); 

      Left = 0; 
      Top = 0; 

      Rectangle rect = new Rectangle { 
       Stroke = System.Windows.Media.Brushes.Black, 
       StrokeThickness = 1, 
       Width = 100, 
       Height = 100 
      }; 

      canvas.Children.Add(rect); 
      Canvas.SetLeft(rect, 50); 
      Canvas.SetTop(rect, 50); 
     } 

     private void keyPressed(object sender, System.Windows.Input.KeyEventArgs e) { 
      System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap((int)Width, (int)Height); 

      System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap); 

      canvas.Children.Clear(); 
      graphics.CopyFromScreen(0, 0, 0, 0, 
            new System.Drawing.Size(bitmap.Width, bitmap.Height), 
            System.Drawing.CopyPixelOperation.SourceCopy); 

      String path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
      path += "\\MuckleEwesPic.png"; 

      bitmap.Save(path, System.Drawing.Imaging.ImageFormat.Png); 
     } 
    } 
} 

如何清除畫布,然後採取了截屏沒有這種現象發生?沒有'不添加矩陣'不是一個解決方案哈,這只是一個更大的應用程序,其中發生問題的最小例子。

謝謝。

+2

請立即從應用程序中刪除對「System.Drawing」的所有引用。 WPF不需要,也不關心這一點。 –

+1

您需要一個佈局和渲染過程才能發生......請參閱:http://social.msdn.microsoft。com/Forums/vstudio/zh-CN/693fbedb-efa6-413e-ab66-530c6961d3fb /如何等待wpf-render-thread-to-catch-up –

+0

使用動畫並且可以完成動畫事件 –

回答

1

使用類似的ColinSmith的鏈接:

static void WaitForRenderPass() 
{ 
    Application.Current.Dispatcher 
    .BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {})) 
    .Wait(); 
} 

排序作品的等待在渲染過程,但問題是這是不可能的(據我所知)說,如果該渲染過程包含了你想要的一切。

實際上取決於系統負載/視頻卡驅動程序/ ...它必須被多次調用。我有一臺機器必須在循環中調用3次,每次調用都需要2幀(60Hz)才能完成。只有這樣,上面的調用纔會立即返回,表明渲染線程真的處於空閒狀態,這可能意味着您想要渲染的所有更改都會被渲染,這意味着屏幕捕獲包含了他們應該擁有的所有內容。所以我們結束了使用

for(int i = 0 ; i < 5 ; ++i) 
{ 
    WaitForRenderPass(); 
    Thread.Sleep(10); 
} 

這是醜陋的,它是一個黑客,但它並沒有失敗(還)。

關於HighCore的評論:你可以捕獲屏幕with Wpf-only classes爲好,但是:

  • 它具有OP擺在首位,所以它不會立即解決任何問題開始這個questiomn對於同樣的問題(除由於沒有使用System.Drawing中)
  • ,你將無法在捕獲
  • 獲得主窗口的鉻是明顯高於CopyScreen慢
  • 它不會呈現完全相同的像素作爲渲染到屏幕