HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Update bitmap in picturebox with data from a socket

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pictureboxupdatewithbitmapsocketfromdata

Problem

I'm working on a screen sharing project, and I receive a small block of images from a Socket constantly. I need to update them on a certain initial desktop bitmap I have.

After receiving every block, it copies its pixels according to a specific position (X and Y parameters), which is how the initial image gets updated. But then comes the part where I need to display it on a Picturebox. I handle the Paint event and redrawing it all again. The entire initial image is pretty big (1920X1080 in my case).

private void MainScreenThread()
{
    ReadData();//reading data from socket.
    initial = bufferToJpeg();//first intial full screen image.
    pictureBox1.Paint += pictureBox1_Paint;//activating the paint event.
    while (true)
    {
        int pos = ReadData();
        x = BlockX();//where to draw :X
        y = BlockY();//where to draw :Y
        Bitmap block = bufferToJpeg();//constantly reciving blocks.
        Draw(block, new Point(x, y));//applying the changes-drawing the block on the big initial image.

        this.Invoke(new Action(() =>
        {
            pictureBox1.Refresh();//updaing the picturebox for seeing results.
            // this.Text = ((pos / 1000).ToString() + "KB");
        }));
    }
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    lock (initial)
    {
        e.Graphics.DrawImage(initial, pictureBox1.ClientRectangle); //draws at picturebox's bounds
    }
}


Because I'm aiming at high speed performance (it's kind of a real-time project), I would like to know if there's any method to draw the block itself on the picturebox instead of drawing the whole initial bitmap again. Plus, scaling it to the Picuturebox bounds seems too inefficient to me.

The picturebox itself is not resizeable - it has a fixed width and height. But I need to scale the initial Bitmap every time (after processing the blocks) so it will fit the picturbox bounds to allow the client to see the full image. Despite their

Solution

If your blocks don't change size, why not create adjacent picture boxes so that you update each one individually?

If that isn't providing enough performance, remove the picture box altogether and create a custom user control where you override the OnPaint method and do your drawing inside of it.

This way, the you will pass your user control an array of bitmaps to draw and where to draw them and, when OnPaint gets called, you simply use DrawImage() to place each one at the appropriate location.

No need for you to join the bitmaps manually.

Should a new a image arrive and you want to force redrawing, simply call Invalidate() on the user control which will force OnPaint to be called.
This can be optimized even further as Invalidate can be called only on a specific region of your control, allowing you to only redraw the parts that are necessary.

Context

StackExchange Code Review Q#135078, answer score: 3

Revisions (0)

No revisions yet.