Ove*_*ars 5 c# memory graphics unsafe buffered
我需要将1027*768位图渲染到客户端窗口(相同大小),并且我没有超过10-15 ms来完成此任务.我使用bufferedGraphics从分配bufferedGraphicsContect对象,仍然看到巨大的性能问题.
我使用不安全的代码来执行我的复制操作,并找到了令人难以置信的结果.我知道Graphics/BufferedGraphics对象应该在内存中有某种绘图表面.我想知道是否有人能指出我如何使用Marshal或其他一些不安全的低级方法写入这个表面的正确方向.
我正在移植旧的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();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
忘记提到我正在寻找Graphics.DrawImage()的低级替代品,最好使用指针写入Graphics表面内存?再次感谢
注意位图的像素格式。在标准 32bpp 视频硬件上,Format32bppPArgb 的渲染速度比任何其他硬件快十倍。因为像素不需要任何平移。您现在使用的 24bpp 格式需要扩展到 32bpp,而且这不是免费的。不要跳过 PArgb 的 P,也不要忘记在代码中将 alpha 值设置为 255。
顺便说一句,使用 BufferedGraphics 是可疑的。您应该始终使用 OnPaint 方法中免费获得的那个。而且您可能根本不需要它,因为您的位块传送速度如此之快。这是自动 2 倍加速。
| 归档时间: |
|
| 查看次数: |
1056 次 |
| 最近记录: |