image - Saving Surface to Bitmap and optimizing DirectX screen capture in C# -
after whole day of testing came code, captures current screen using directx (slimdx) , saves file:
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; }
then following:
dxscreencapture sc = new dxscreencapture();
..code here
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); }
the results are:
0. when don't save surface: avg. elapsed time: 80-90ms
1. when save surface bmp file: format: imagefileformat.bmp , avg. elapsed time: 120ms, file size: 7mb
2. when save surface png file: format: imagefileformat.png , avg. elapsed time: 800ms, file size: 300kb
the questions are:
1. possible optimise current image capture? according article - directx screen capture should faster gdi. me, gdi takes 20ms "bitmap", whereas takes 80ms "surfare" using dx (both without saving).
http://www.codeproject.com/articles/274461/very-fast-screen-capture-using-directx-in-csharp
2a. how save surface png image format faster? when save surface 7mb bmp file takes 6 times less time, when save same surface 300kb png file..
2b. possible save surface directly bitmap don't have create temporary files?
so don't have following: surface -> image file; image file open -> bitmap;, instead: surface -> bitmap
that's now. i'll gladly accept tips, thanks!
edit:
just solved 2b doing:
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");
is faster than:
bitmap bitmap = new bitmap(slimdx.direct3d9.surface.tostream(s, slimdx.direct3d9.imagefileformat.bmp));
by 100 ms!!! yeah, couldn't believe eyes ;) don't idea of temporary file creation, 50% performance increase (100-200ms instead of 200-300+) thing.
if don't want use slimdx library can try
public bitmap gimmebitmap(surface s) { graphicsstream gs = surfaceloader.savetostream(imagefileformat.bmp, s); return new bitmap(gs); }
and try same .png - did not tested performance it have to faster using disc temporary file :)
and 1st question - try once create surface , on every screenshot put device's buffer data , create bitmap
d.getfrontbufferdata(0, s); return new bitmap(surfaceloader.savetostream(imagefileformat.bmp, s));
this should save time :)
Comments
Post a Comment