编程语言
首页 > 编程语言> > 用C#绘制一系列位图的最快方法

用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