Самый быстрый способ нарисовать серию растровых изображений с C # - PullRequest
3 голосов
/ 01 октября 2010

Я создаю приложение, которое захватывает видеокадры с камеры (30fps @ 640x480), обрабатывает их, а затем отображает их в форме Windows.Первоначально я использовал DrawImage (см. Код ниже), но производительность была ужасной.Даже с отключенным этапом обработки лучшее, что я могу получить, это 20fps на 2,8 ГГц процессоре Core 2 Duo.Двойная буферизация включена в форме Windows, в противном случае я получаю разрыв.

Примечание. Используемое изображение является растровым изображением формата Format24bppRgb.Я знаю, что DrawImage должен работать быстрее с отформатированным изображением Format32bppArgb, но я ограничен форматом, который выходит из фрейм-граббера.ниже) но производительность была еще хуже.Я очень новичок в программировании 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.Кажется, это должно быть очень просто.

Ответы [ 2 ]

3 голосов
/ 10 января 2012

Ответ прямо перед вами. Это поздний ответ на старый вопрос, но кому-то может понадобиться ответ, так что ...

Вместо того, чтобы объявлять новые текстуры и прямоугольники в цикле рисования (что довольно интенсивно для ресурсов), почему бы не создать текстуру вне области видимости? Например, вместо своего попробуйте следующее:

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();
}

и затем, если вам нужно инициировать несколько текстур, сделайте это в списке, а затем рисуйте из этого списка. Это избавляет от необходимости использовать ресурсы, а затем освобождает их каждую краску.

0 голосов
/ 01 октября 2010

CameraViewForm - ваше окно просмотра? Если это так, то при рисовании перерисовывается все окно, включая все кнопки, индикаторы выполнения и т. Д. Это будет более или менее дорого в зависимости от количества элементов управления в форме и визуальных папок, которые вы включили для рабочего стола. элементы в различных ОС (например, прозрачность панели окна).

Попробуйте выполнить одиночную буферизацию всей формы, но предоставьте Panel (из которой я предполагаю, что вы получаете displayRectangle) свой собственный BufferedGraphicsContext, объявив новый при вызове GreateGraphics () или перед вызовом Invalidate () на Panel. Это позволяет использовать двойную буферизацию Panel отдельно от формы.

...