Мне нужно отобразить растровое изображение 1027 * 768 для окна клиента (такого же размера), и у меня нет более 10-15 мс для выполнения этой задачи. Я использую bufferedGraphics, выделенный из объекта bufferedGraphicsContect и по-прежнему замечает огромные проблемы с производительностью.Запись на буферную поверхность графики с помощью манипуляции с указателем
Я использую небезопасный код, чтобы выполнять свои операции копирования и обнаружили невероятные результаты. Я знаю, что объекты Graphics/BufferedGraphics должны иметь вид поверхности изображения в памяти. Мне было интересно, может ли кто-нибудь указать мне в правильном направлении, как писать на эту поверхность, используя маршал или какой-нибудь другой небезопасный метод низкого уровня.
Я в процессе портирования старого графического приложения C#. Я знаю, что C# не предназначен для тяжелой графики и что есть более эффективные инструменты, чем GDI +, к сожалению, у меня нет такой роскоши.
Это то, что я придумал до сих пор ... Любое понимание того, что так когда-либо сильно связано.
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:
забыл упомянуть, что я ищу альтернативу низкого уровня к Graphics.DrawImage(), предпочтительно писать на поверхности памяти графики, используя указатели? Еще раз спасибо
Я отредактировал отступ кода и, похоже, в конце фигурки фигурного скобки. Если это было проблемой на моем конце, пожалуйста, откиньте мое редактирование – puk
Спасибо за помощь, я думаю, что скобка тоже часть моего виновата, извините :) – OverMars