sau một ngày toàn bộ thử nghiệm tôi đã đưa ra mã này, mà chụp màn hình hiện tại sử dụng DirectX (SlimDX) và lưu nó vào một tập tin:Saving Surface to Bitmap và tối ưu hóa chụp ảnh màn hình DirectX trong C#
Device d;
public DxScreenCapture()
{
PresentParameters present_params = new PresentParameters();
present_params.Windowed = true;
present_params.SwapEffect = SwapEffect.Discard;
d = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.SoftwareVertexProcessing, present_params);
}
public Surface CaptureScreen()
{
Surface s = Surface.CreateOffscreenPlain(d, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, Format.A8R8G8B8, Pool.Scratch);
d.GetFrontBufferData(0, s);
return s;
}
sau đó, tôi làm như sau:
DxScreenCapture sc = new DxScreenCapture();
..code đây
private void button1_Click(object sender, EventArgs e)
{
Stopwatch stopwatch = new Stopwatch();
// Begin timing
stopwatch.Start();
Surface s = sc.CaptureScreen();
Surface.ToFile(s, @"c:\temp\test.png", ImageFileFormat.Png);
s.Dispose();
stopwatch.Stop();
textBox1.Text = ("Elapsed:" + stopwatch.Elapsed.TotalMilliseconds);
}
các kết quả là:
0. khi tôi không lưu bề mặt: avg. thời gian trôi qua: 80-90ms
1. khi tôi cũng lưu bề mặt thành tệp BMP: định dạng: ImageFileFormat.Bmp, avg. thời gian trôi qua: 120 mili giây, kích thước tệp: 7mb
2. khi tôi cũng lưu bề mặt vào tệp PNG: định dạng: ImageFileFormat.Png, avg. thời gian trôi qua: 800ms, kích thước: 300KB
Các câu hỏi là:
1. Có thể tối ưu hóa khả năng chụp ảnh hiện tại? Theo bài viết này - Chụp ảnh màn hình Directx phải nhanh hơn GDI. Đối với tôi, GDI thường mất 20ms để có được một "Bitmap", trong khi phải mất 80ms để có được "Surfare" bằng cách sử dụng DX (cả hai mà không lưu).
http://www.codeproject.com/Articles/274461/Very-fast-screen-capture-using-DirectX-in-Csharp
2a. Làm thế nào để lưu Surface thành định dạng hình ảnh PNG nhanh hơn? Khi tôi lưu bề mặt thành tệp BMP 7MB, thời gian sẽ mất gần 6 lần ít hơn, khi tôi lưu cùng một bề mặt vào tệp PNG 300kb ..
2b. Có thể lưu Bề mặt trực tiếp vào Bitmap để không phải tạo các tệp tạm thời không?
Vì vậy, tôi không phải làm như sau: Bề mặt -> tệp hình ảnh; tệp hình ảnh mở -> bitmap;, nhưng thay vào đó: Bề mặt -> bitmap
là tất cả bây giờ. Tôi sẽ sẵn sàng chấp nhận bất kỳ lời khuyên nào, cảm ơn!
Edit:
Chỉ cần giải quyết 2b bằng cách thực hiện:
Bitmap bitmap = new Bitmap(SlimDX.Direct3D9.Surface.ToStream(s, SlimDX.Direct3D9.ImageFileFormat.Bmp));
Edit2:
Surface.ToFile(s, @"C:\temp\test.bmp", ImageFileFormat.Bmp);
Bitmap bitmap = new Bitmap(@"C:\temp\test.bmp");
nhanh hơn:
Bitmap bitmap = new Bitmap(SlimDX.Direct3D9.Surface.ToStream(s, SlimDX.Direct3D9.ImageFileFormat.Bmp));
bởi 100 ms !!!Vâng, tôi không thể tin vào mắt mình nữa;) Tôi không thích ý tưởng tạo tập tin tạm thời, nhưng tăng hiệu suất 50% (100-200ms thay vì 200-300 +) là một điều rất tốt.
Tôi nghĩ png có thể nén nhanh hơn 800 mili giây. Hãy thử nếu nó là nhanh hơn nếu bạn lần đầu tiên ghi vào một bộ nhớ. –