Ich muss eine 1027 * 768 Bitmap zum Client-Fenster (gleiche Größe) und ich habe nicht mehr als 10-15 ms, um diese Aufgabe abzuschließen. Ich verwende BufferedGraphics zugewiesen von einem bufferedGraphicsContect Objekt und beachten Sie immer noch große Performance-Probleme.Schreiben auf gepufferte Grafikoberfläche über Zeigermanupilation
ich unsicheren Code bin mit meinen Kopiervorgänge und gefunden unglaubliche Ergebnisse durchzuführen. Ich weiß, dass die Graphics/BufferedGraphics Objekte eine Art von Zeichnungsoberfläche in Speicher haben sollten. Ich habe mich gefragt, ob mir jemand in die richtige Richtung zeigen könnte, wie man mit Marshal oder einer anderen unsicheren Low-Level-Methode auf diese Oberfläche schreibt.
Ich bin in den Prozess der eine ältere C# Grafikanwendung zu portieren. Ich weiß, dass C# nicht für schwere Grafiken ausgelegt ist und dass es bessere Werkzeuge als GDI + gibt, leider habe ich diesen Luxus nicht.
Dies ist, was ich mit so weit gekommen sind ... Jeder Einblick, was so überhaupt stark apperciated.
byte[] _argbs = null;
static readonly Bitmap _bmUnderlay = Properties.Resources.bg;
static Bitmap _bmpRender = new Bitmap(1024, 768, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
int bmpHeight = Properties.Resources.bg.Height;
int bmpWidth = Properties.Resources.bg.Width;
static BufferedGraphicsContext _bgc = new BufferedGraphicsContext();
internal unsafe void FillBackBuffer(Point cameraPos)
{
// lock up the parts of the original image to read (parts of it)
System.Drawing.Imaging.BitmapData bmd = _bmUnderlay.LockBits(
new Rectangle(cameraPos.X, cameraPos.Y, 1024, 768),
System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// get the address of the first line.
IntPtr ptr = bmd.Scan0;
//if (_argbs == null || _argbs.Length != bmd.Stride * bmd.Height)
// _argbs = new byte[bmd.Stride * bmd.Height];
if (_argbs == null || _argbs.Length != 1024 * 3 * 768)
_argbs = new byte[1024 * 3 * 768];
// copy data out to a buffer
Marshal.Copy(ptr, _argbs, 0, 1024 * 3 * 768);
_bmUnderlay.UnlockBits(bmd);
// lock the new image to write to (all of it)
System.Drawing.Imaging.BitmapData bmdNew = _bmpRender.LockBits(
new Rectangle(0, 0, 1024, 768),
System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// copy data to new bitmap
Marshal.Copy(_argbs, 0, bmdNew.Scan0, 1024 * 3 * 768);
_bmpRender.UnlockBits(bmdNew);
}
private unsafe void _btnGo_Click(object sender, EventArgs e)
{
// less than 2 ms to complete!!!!!!!!
FillBackBuffer(new Point());
using (BufferedGraphics bg = _bgc.Allocate(CreateGraphics(), ClientRectangle))
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
/////
///
// This method takes over 17 ms to complete
bg.Graphics.DrawImageUnscaled(_bmpRender, new Point());
//
///
/////
sw.Start();
this.Text = sw.Elapsed.TotalMilliseconds.ToString();
bg.Render();
}
}
EDIT:
vergessen Ich suche nach einem niedrigen Niveau Alternative zu Graphics.DrawImage() zu erwähnen, vorzugsweise auf Grafikoberfläche Speicher zu schreiben, mit Zeigern? Danke nochmal
Ich habe den Codeeinzug bearbeitet und es scheint eine danging geschweifte Klammer am Ende zu haben. Wenn dies ein Problem auf meinem Ende ist, bitte meine bearbeiten – puk
Danke für die Hilfe zurückrollen, ich denke, die Klammer Teil meiner Schraube ist auch nach oben, sorry :) – OverMars