2016-06-21 22 views
1

Ich versuche, eine einfache Videoaufnahme eines bestimmten Fensters zu erstellen, indem ein Screenshot des Fensters alle x Millisekunden (kombinieren Sie dann alle diese Bilder in einer AVI-Datei), aber ich nicht wie zu definieren der Wert x. Wie definiere ich es? Wofür wird ein gemeinsamer Wert verwendet? Ich habe etwas über 24fps gelesen.Erstellen einer Bildschirmaufnahme

Ich bin mir auch nicht sicher, ob die Verwendung einer Timer, die Aufnahme in der Tick Veranstaltung ist eine gute Idee. Habe ich irgendeine Art von Ungenauigkeit und ich sollte etwas anderes verwenden? Beispielsweise dauert der Screenshot aus irgendeinem Grund länger als erwartet.

Meine aktuelle Implementierung ist wie folgt:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    static extern bool GetWindowRect(IntPtr hWnd, out RECT r); 

    public Bitmap GetScreenshot(IntPtr hwnd) 
      { 
       RECT rc; 

       if (!GetWindowRect(hwnd, out rc)) 
        throw new Win32Exception(Marshal.GetLastWin32Error()); 

       Bitmap bmp = new Bitmap(rc.right - rc.left, rc.bottom - rc.top, PixelFormat.Format32bppArgb); 
       using (var gfxBmp = Graphics.FromImage(bmp)) 
       { 
        IntPtr hdcBitmap = gfxBmp.GetHdc(); 
        bool succeeded = PrintWindow(hwnd, hdcBitmap, 0); 
        gfxBmp.ReleaseHdc(hdcBitmap); 
        if (!succeeded) 
        { 
         gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size)); 
        } 
        IntPtr hRgn = CreateRectRgn(0, 0, 0, 0); 
        GetWindowRgn(hwnd, hRgn); 
        Region region = Region.FromHrgn(hRgn); 
        if (!region.IsEmpty(gfxBmp)) 
        { 
         gfxBmp.ExcludeClip(region); 
         gfxBmp.Clear(Color.Transparent); 
        } 
        return bmp; 
       } 
      } 

und

int i = 0; 
    const string dest_path = @"C:\Users\pc2\Desktop\images"; 
    void doRecord() 
    { 
     string filename = Path.Combine(dest_path, string.Format("{0}.png", ++i)); 
     // yeah, I'll add some error checking here soon as it gets working. 
     GetScreenshot(handle).Save(filename, ImageFormat.Png); 
    } 

und in der Zecke-Ereignis des Timer Ich nenne es:

private void timer1_Tick(object sender, EventArgs e) 
     { 
      doRecord(); 
     } 

auch, wie man richtig definieren, um Wert von x, fehle ich etwas?

+0

Ich hatte eine ähnliche Herausforderung und die gefundene Lösung war es, die Bilder in den Speicher zu senden, dann einen anderen Thread ziehen ein Bild in Abständen. Ja, es ist * hacky * aber meine Timeline war perfekt für die Aufnahme. Hoffentlich hilft das! – Spencer

Antwort

1

Sie müssen den Parameter 'Interval' für den von Ihnen verwendeten Timer einstellen. Das 'Intervall' wird in Millisekunden festgelegt, wenn Sie also ~ 24 FPS haben wollen, setzen Sie 'Intervall' auf 42 (1000 (Millisekunden in einer Sekunde)/24 (gewünschte FPS) = 42).

+0

Tut mir leid, wenn das nicht klar ist, meine Frage ist, was ein gutes Intervall ist, um den screnshot zu nehmen. Mir ist bewusst, wie man die Intervalleigenschaft der Zeit einstellt. – Jack

+2

Meistens ist der FPS, den Sie anstreben sollten, 30 (aber ein Wert, der näher an der Bildwiederholrate Ihres Monitors liegt, der normalerweise 60 ist, wäre besser ..) - das beseitigt das Bildschirmflackern und wenn Sie die Bilder zu einem Video verschmelzen Das sollte ganz nett sein. – brokenisfixed