Necesito renderizar un mapa de bits 1027 * 768 en la ventana del cliente (mismo tamaño) y no tengo más de 10-15 ms para completar esta tarea. Estoy usando con bufferGraphics asignado desde un objeto buffertaficsContect y todavía noto grandes problemas de rendimiento.Escribir en la superficie de gráficos almacenados en el medio de la manupulación del puntero
estoy usando código no seguro para realizar mis operaciones de copia y encontrado resultados increíbles. Sé que los objetos Graphics/BufferedGraphics deberían tener algún tipo de superficie de dibujo en la memoria. Me preguntaba si alguien podría señalarme en la dirección correcta sobre cómo escribir en esta superficie usando Marshal o algún otro método inseguro de bajo nivel.
Estoy en el proceso de portar una aplicación de gráficos C# anterior. Sé que C# no está diseñado para gráficos pesados y que hay mejores herramientas que GDI + disponible, lamentablemente no tengo esos lujos.
Esto es lo que he encontrado hasta ahora ... Cualquier idea de lo que siempre está muy apercinada.
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:
se olvidó de mencionar que estoy buscando una alternativa de bajo nivel a Graphics.DrawImage(), preferiblemente por escrito a la memoria de gráficos de superficie, el uso de punteros? Gracias de nuevo
He editado la sangría del código y parece tener una llave al final. Si esto fue un problema de mi parte, por favor invierta mi edición – puk
Gracias por la ayuda, creo que el corsé es parte de mi error también, lo siento :) – OverMars