C # Bitmap in Picturebox aktualisieren
Ich arbeite an einem Projekt zur Bildschirmfreigabe und erhalte kleine Bildblöcke von einemSocket
ständig und müssen sie auf einem bestimmten Anfang dekstop Bitmap aktualisieren, die ich habe.
rundsätzlich lese ich ständig Daten aus dem Socket (Daten, die als JPEG-Bild gespeichert sind), mitImage.FromStream()
, um das Bild abzurufen und die empfangenen Blockpixel in die vollständige primäre Bitmap zu kopieren (an einer bestimmten PositionX
undY
was ich auch aus dem Socket bekomme) - so wird das ursprüngliche Image aktualisiert. Aber dann kommt der Teil, wo ich es auf einem @ anzeigen muPicturebox
Ich kümmere mich um diePaint
Event und alles noch einmal neu zeichnen - das gesamte ursprüngliche Bild, das ziemlich groß ist (1920 x 1080 in meinem Fall).
Dies ist mein Code:
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.using native memcpy.
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
}
}
Weil ich auf Hochgeschwindigkeitsleistung abziele (es ist eine Art Echtzeitprojekt), würde ich gerne wissen, ob es keine Methode gibt, um den aktuell empfangenen Block selbst auf die Bildbox zu zeichnen, anstatt das ganze @ zu zeichneinitial
Bitmap wieder - was mir sehr ineffizient erscheint ... Dies ist meine Zeichenmethode (funktioniert extrem schnell, Block kopieren mitmemcpy
):
private unsafe void Draw(Bitmap bmp2, Point point)
{
lock (initial)
{
BitmapData bmData = initial.LockBits(new Rectangle(0, 0, initial.Width, initial.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, initial.PixelFormat);
BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp2.PixelFormat);
IntPtr scan0 = bmData.Scan0;
IntPtr scan02 = bmData2.Scan0;
int stride = bmData.Stride;
int stride2 = bmData2.Stride;
int Width = bmp2.Width;
int Height = bmp2.Height;
int X = point.X;
int Y = point.Y;
scan0 = IntPtr.Add(scan0, stride * Y + X * 3);//setting the pointer to the requested line
for (int y = 0; y < Height; y++)
{
memcpy(scan0, scan02 ,(UIntPtr)(Width * 3));//copy one line
scan02 = IntPtr.Add(scan02, stride2);//advance pointers
scan0 = IntPtr.Add(scan0, stride);//advance pointers//
}
initial.UnlockBits(bmData);
bmp2.UnlockBits(bmData2);
}
}
Hier sind einige Beispiele für eine vollständige primäre Bitmap und andere kleine Blöcke, die ich bekomme und die ich über die vollständige ziehen muss.
Vollständige Bitmap: small block:
small block:
Ich erhalte eine große Menge kleiner Blöcke pro Sekunde (30 ~ 40), manchmal sind ihre Grenzen sehr klein (z. B. ein Rechteck mit 100 x 80 Pixel), so dass ein erneutes Zeichnen der gesamten Bitmap nicht erforderlich ist ... Schnelles Aktualisieren eines Vollbilds töte die Leistung ...
ch hoffe, meine Erklärung war kla
ch freue mich auf eine Antwor
Vielen Dank