2009-04-13 36 views
6

Tôi cần phải in các màn hình của ứng dụng Windows rất nhanh để tạo video ra khỏi nó ... Tôi đã sử dụng C# tất cả các cách, nhưng tôi mở cho bất kỳ ngôn ngữ nào mà quá trình này có thể Nhanh hơn.Cách nhanh nhất có thể để bắt màn hình là gì? Bất kỳ ngôn ngữ

Tôi đã sử dụng nhiều kỹ thuật:

  • chức năng .net: Bitmap.CopyFromScreen()
  • GDI
  • Direct3d/DirectX

nhanh nhất tôi đã có được sử dụng GDI và tôi vẫn nhận được ít hơn 10 fotograms mỗi giây. Tôi sẽ cần nhiều hơn một chút, ít nhất là 20 hoặc 30 ...

Có vẻ như rất lạ đối với tôi rằng một thao tác đơn giản như vậy là quá khắt khe. Và có vẻ như sử dụng một cpu nhanh hơn không thay đổi tình hình.

Tôi có thể làm gì? Có thể trực tiếp chụp được bản vẽ của một ứng dụng bằng gdi hay gì đó không? Hoặc thậm chí có thể các chức năng cấp thấp hơn để nắm bắt thông tin bị ném vào card đồ họa?

Mọi ánh sáng về vấn đề này sẽ được đánh giá khá nhiều. Cảm ơn rất nhiều

+0

Từ "fotogram" có phải là từ thực tế không? – bzlm

+0

Có rất nhiều ứng dụng thực hiện điều này thật đẹp mắt. Bạn có chắc chắn muốn phát minh lại bánh xe không? –

+1

Hãy xem ... đây có phải là trang web "ứng dụng hữu ích" hay trang web câu hỏi lập trình không? Đó là một trong số họ, nhưng tôi vẫn quên điều đó. – bzlm

Trả lời

1

Rất nhiều chương trình sử dụng trình điều khiển và cho phép ứng dụng của bạn nối vào thói quen hiển thị mức thấp hơn. Tôi không chắc chắn chính xác làm thế nào điều này được thực hiện, nhưng nó là có thể. Đây là điểm bắt đầu khi viết trình điều khiển Windows. http://msdn.microsoft.com/en-us/library/ms809956.aspx

Dưới đây là một cái gì đó tôi chỉ tìm thấy qua Google: http://www.hmelyoff.com/index.php?section=17

+0

Tại sao tôi bị bỏ phiếu? –

+0

Ah, câu hỏi vĩnh cửu. – bzlm

+1

Liên kết Google đã chết. Nó sẽ giúp để có một đoạn trích, cho những dịp như vậy. – JYelton

1

Bạn có thể muốn sử dụng cái gì đó như Camtasia. Phụ thuộc vào lý do bạn tạo video.

Tôi sử dụng phiên bản viết lại của Jeff's User-Friendly Exception Handling và anh ấy sử dụng BitBlt từ GDI để chụp ảnh màn hình. Có vẻ đủ nhanh với tôi, nhưng tôi đã không đánh giá nó, và chúng tôi chỉ sử dụng nó cho một bức ảnh tại một thời điểm khi có một ngoại lệ unhandled ném.

#region Win32 API screenshot calls 

// Win32 API calls necessary to support screen capture 
[DllImport("gdi32", EntryPoint = "BitBlt", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] 
private static extern int BitBlt(int hDestDC, int x, int y, int nWidth, int nHeight, int hSrcDC, int xSrc, 
           int ySrc, int dwRop); 

[DllImport("user32", EntryPoint = "GetDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] 
private static extern int GetDC(int hwnd); 

[DllImport("user32", EntryPoint = "ReleaseDC", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] 
private static extern int ReleaseDC(int hwnd, int hdc); 

#endregion 

private static ImageFormat screenshotImageFormat = ImageFormat.Png; 

/// <summary> 
/// Takes a screenshot of the desktop and saves to filename and format specified 
/// </summary> 
/// <param name="fileName"></param> 
private static void TakeScreenshotPrivate(string fileName) 
{ 
    Rectangle r = Screen.PrimaryScreen.Bounds; 

    using (Bitmap bitmap = new Bitmap(r.Right, r.Bottom)) 
    { 
     const int SRCCOPY = 13369376; 

     using (Graphics g = Graphics.FromImage(bitmap)) 
     { 
      // Get a device context to the windows desktop and our destination bitmaps 
      int hdcSrc = GetDC(0); 
      IntPtr hdcDest = g.GetHdc(); 

      // Copy what is on the desktop to the bitmap 
      BitBlt(hdcDest.ToInt32(), 0, 0, r.Right, r.Bottom, hdcSrc, 0, 0, SRCCOPY); 

      // Release device contexts 
      g.ReleaseHdc(hdcDest); 
      ReleaseDC(0, hdcSrc); 

      string formatExtension = screenshotImageFormat.ToString().ToLower(); 
      string expectedExtension = string.Format(".{0}", formatExtension); 

      if (Path.GetExtension(fileName) != expectedExtension) 
      { 
       fileName += expectedExtension; 
      } 

      switch (formatExtension) 
      { 
       case "jpeg": 
        BitmapToJPEG(bitmap, fileName, 80); 
        break; 
       default: 
        bitmap.Save(fileName, screenshotImageFormat); 
        break; 
      } 

      // Save the complete path/filename of the screenshot for possible later use 
      ScreenshotFullPath = fileName; 
     } 
    } 
} 

/// <summary> 
/// Save bitmap object to JPEG of specified quality level 
/// </summary> 
/// <param name="bitmap"></param> 
/// <param name="fileName"></param> 
/// <param name="compression"></param> 
private static void BitmapToJPEG(Image bitmap, string fileName, long compression) 
{ 
    EncoderParameters encoderParameters = new EncoderParameters(1); 
    ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg"); 

    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, compression); 
    bitmap.Save(fileName, codecInfo, encoderParameters); 
} 
+0

Chris, giải pháp gdi tôi đã làm rất giống với giải pháp bạn đăng, nhưng vì nó có một số khác biệt nên tôi đã quyết định dùng thử. Tuy nhiên, nó không nhận ra các hàm "GetDC", "BiBlt" và "ReleaseDC". Các chức năng này có được viết bởi bạn không? Bạn có thể cung cấp cho tôi với họ? –

+0

Các hàm này là các hàm được tham chiếu bởi các thuộc tính DllImport. Tôi tin rằng những người nên tham khảo gdi32.dll và user32.dll tự động. –

Các vấn đề liên quan