0

The main goal is to get all pixels from the bitmap very fast, and now this is done in 30fps.

I save the bitmap to byte[] array which has length: 4196406(4mb).

This is the code I use which give me ~5fps:

using (var data = new MemoryStream())
{
    bitmap.Save(data, ImageFormat.Bmp);
    ScreenRefreshed?.Invoke(this, data.ToArray());
    _init = true;
}

Color[,] Pixels = new Color[Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height]; 

Pixels = GetPixels(data);

public Color[,] GetPixels(byte[] data)
{
    int width = Screen.PrimaryScreen.Bounds.Width;
    int height = Screen.PrimaryScreen.Bounds.Height;
    Int32 stride = width * 4;
    Int32 curRowOffs = (((width * height * 4) + 54) - 1) - stride;

    Color[,] buffer = new Color[width, height];

    for (uint y = 0; y < height; y++)
    {
        uint index = (uint)curRowOffs;      
        for (uint x = 0; x < width; x++)
        {
            if (index >= 0)
            {
                var b = data[index];
                var g = data[index + 1];
                var r = data[index + 2];
                var a = data[index + 3];

                buffer[x, y] = Color.FromArgb(a,r,g,b); //This line is reducing the fps
            }
            index += 4;
        }
        curRowOffs -= stride;
    }
    return buffer;
}

How to assign the values of array to another one and loop through the second array keeping the same speed(30fps)?

This line: buffer[x, y] = Color.FromArgb(a,r,g,b); - reduces fps from 30 to 5

atiyar
  • 7,762
  • 6
  • 34
  • 75
Eamrle
  • 3
  • 1
  • I think that you are already pushing too hard by saving the bitmap in the BMP format and then extracting the pixels back to the color matrix... I mean, all the colors (pixels) you are chasing for are already present and stored in the bitmap buffer... maybe not in the precise form you want them, but, the main question is - what are you trying to achieve? – Dusan Mar 07 '21 at 22:33
  • There are very efficient ways of analyzing/manipulating the raw pixel data... far better then the approach you are starting with... So, the main question is not how to optimize the loop or fill up the color matrix faster - but - what are you are trying to achieve... then we can help. – Dusan Mar 07 '21 at 22:39
  • I want to get RGBA values from that byte array and to loop through fast – Eamrle Mar 07 '21 at 22:41
  • 4
    Then you can easily use the `Bitmap.Scan0` approach https://learn.microsoft.com/en-us/dotnet/api/system.drawing.imaging.bitmapdata.scan0?view=net-5.0 or even faster `unsafe` approach https://stackoverflow.com/a/1563170/461810 – Dusan Mar 07 '21 at 22:44
  • 1
    Does this answer your question? [Fast work with Bitmaps in C#](https://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp) – Charlieface Mar 08 '21 at 00:22
  • 1
    If you want to manage bitmap data fast you are bound to use "raw maths" and array indexes/pointers with "unsafe" Like @Dusan advices – DrkDeveloper Mar 08 '21 at 02:24
  • 1
    I would not recommend using a `Color[,]` structure. A color struct is 12 bytes, 4 times larger than needed. It would be more efficient to work on the byte-array directly, optionally converting a pixel to a color value on demand. – JonasH Mar 08 '21 at 08:00

0 Answers0