-1

I'm taking a screenshot, shrinking it down to 50% of resolution,to take less space and then I put bytes in the buffer, however unfortunately this process takes too much time.

Currently it takes from 60 to 100ms for 1920x1080 source resolution, this causes that the output video at 30fps is speeded up as I'm not producing screenshots fast enough. I need to achieve about 40ms to make video that I make out of it fluent.

Question: How can I apply a faster interpolation algorithm or limit the required operation to speed it up?

public void Screenshot(byte[] buffer)
{
    using (var bmp = new Bitmap(Params.SourceWidth, Params.SourceHeight))
    {
        using (var g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, new Size(Params.SourceWidth, Params.SourceHeight), CopyPixelOperation.SourceCopy);
            g.Flush();
            using (Bitmap resized = new Bitmap(bmp, new Size(Params.TargetWidth, Params.TargetHeight)))
            {
                var bits = resized.LockBits(new Rectangle(0, 0, Params.TargetWidth, Params.TargetHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
                Marshal.Copy(bits.Scan0, buffer, 0, buffer.Length);
                resized.UnlockBits(bits);
            }
        }
    }
}
Yoda
  • 17,363
  • 67
  • 204
  • 344
  • 1
    Like I asked on your previous question on this subject, now deleted, just for context: are you trying to invent your own Remote Desktop Protocol? – CodeCaster Apr 08 '19 at 17:41
  • @CodeCaster No, I'm trying to feed `SharpAvi` with bitmaps as fast as I can to record desktop and 60ms - 100ms is too slow, – Yoda Apr 08 '19 at 17:44
  • Have you tried any of the options from https://stackoverflow.com/questions/1922040/how-to-resize-an-image-c-sharp ? – mjwills Apr 08 '19 at 21:22
  • Have you considered multi-threading this? Most modern desktop CPUs have multiple cores. – Mark Setchell Apr 10 '19 at 15:38

1 Answers1

1

This approach is slow because you're using GDI, which is no longer the main graphics API in Windows (and hasn't been since Windows Vista). One of the reasons it's slow is because it copies image data from your GPU's memory (VRAM) into your computer's main memory (RAM) for it to be manipulated with through GDI.

If you want fast operations on your computer's framebuffer, use the DWM APIs and only copy memory between buffers in your GPU. You can probably also do the image resizing and other operations really fast by doing them as shaders or CUDA programs.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • Thank you for your input. I know why it is slow, however there is a lot of answers suggesting solutions, but none showing an example how to speed it up in C# and actually use sth else than GDI. – Yoda Apr 08 '19 at 17:32
  • 1
    @Yoda There aren't any suggestions for improving it with C# and GDI because it just isn't possible. You have to use a lower-level and more direct API if you want it to be faster. – Dai Apr 08 '19 at 17:39
  • Since you posted your answer I am looking for any DWM sample and can't find any. I was thinking about calling c++ code if I can use this DWM there and return byte[] array from it, but first I need find any sample. – Yoda Apr 08 '19 at 17:53
  • @Yoda It's not that simple as calling some C++ code that emits a `Byte[]` because that managed array must exist in main memory. Fast graphics involves running code that executes on the GPU and operates on VRAM and not code that runs on the CPU and uses main memory. – Dai Apr 08 '19 at 18:01
  • Ok so, are there any C++ based samples,(the whole recording in C++). I tried more stuff, doesn't work, is outdated, for Ubuntu etc. – Yoda Apr 08 '19 at 18:38
  • Will OpenCV help in thi subject? – Yoda Apr 08 '19 at 21:39