用C#绘制一系列位图的最快方法
作者:互联网
我正在构建一个应用程序,该应用程序从摄像机(30fps @ 640×480)捕获视频帧,进行处理,然后在Windows窗体上显示它们.我最初使用的是DrawImage(请参见下面的代码),但是性能太差了.即使禁用了处理步骤,在2.8GHz Core 2 Duo机器上,我所能获得的最佳效果还是20fps. Windows窗体上启用了双缓冲,否则我会撕裂.
注意:所使用的图像是格式为24bppRgb的位图.我知道使用Format32bppArgb格式的图像应该可以使DrawImage更快,但是我受到帧捕获器发出的格式的限制.
private void CameraViewForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// Maximize performance
g.CompositingMode = CompositingMode.SourceOver;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.SmoothingMode = SmoothingMode.None;
g.DrawImage(currentFrame, displayRectangle);
}
我尝试将Managed DirectX 9与Textures和Spites一起使用(请参见下文),但性能甚至更差.我对DirectX编程非常陌生,因此这可能不是最好的DirectX代码.
private void CameraViewForm_Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
device.BeginScene();
Texture texture = new Texture(device, currentFrame, Usage.None, Pool.Managed);
Rectangle textureSize;
using (Surface surface = texture.GetSurfaceLevel(0))
{
SurfaceDescription surfaceDescription = surface.Description;
textureSize = new Rectangle(0, 0, surfaceDescription.Width, surfaceDescription.Height);
}
Sprite sprite = new Sprite(device);
sprite.Begin(SpriteFlags.None);
sprite.Draw(texture, textureSize, new Vector3(0, 0, 0), new Vector3(0, 0, 0), Color.White);
sprite.End();
device.EndScene();
device.Present();
sprite.Dispose();
texture.Dispose();
}
我需要在XP,Vista和Windows 7上运行它.我不知道是否值得尝试XNA或OpenGL.这似乎应该是一件非常简单的事情.
解决方法:
答案就在您眼前.这是一个老问题的较晚答案,但有人可能需要答案,所以…
与其在绘制循环内声明新的纹理和矩形(这在资源上非常密集),不如在范围之外创建纹理?例如,代替您的一个,请尝试以下操作:
Texture texture;
Rectangle textureSize;
private void InitiateTexture()
{
texture = new Texture(device, new Bitmap("CAR.jpg"), Usage.None, Pool.Managed);
using (Surface surface = texture.GetSurfaceLevel(0))
{
SurfaceDescription surfaceDescription = surface.Description;
textureSize = new Rectangle(0, 0,
surfaceDescription.Width,
surfaceDescription.Height);
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, Color.DarkSlateBlue, 1.0f, 0);
device.BeginScene();
Sprite sprite = new Sprite(device);
sprite.Begin(SpriteFlags.None);
sprite.Draw(texture, textureSize,
new Vector3(0, 0, 0),
new Vector3(0, 0, 0), Color.White);
sprite.End();
device.EndScene();
device.Present();
}
然后如果您需要启动多个纹理,则将其制成一个列表,然后从该列表进行绘制.这样可以节省使用资源,然后释放每种涂料的资源.
标签:video,directx,drawimage,c,net 来源: https://codeday.me/bug/20191209/2096343.html