Как рендерить видео из сырых кадров в WPF? - PullRequest
1 голос
/ 05 августа 2009

У меня есть специальная видеокамера (использующая протокол GigEVision), которой я управляю с помощью предоставленной библиотеки. Я могу подписаться на событие получения кадра и затем получить доступ к данным кадра через IntPtr.

В моем старом приложении WinForms я мог визуализировать фрейм, создав объект Bitmap из данных и установив его в изображение PictureBox, или передав дескриптор PictureBox функции в предоставленной библиотеке, которая рисовала бы непосредственно в области .

Какой самый лучший и быстрый способ сделать подобное в WPF? Видеокамера работает от 30 до 100 кадров в секунду.

редактирование (1):

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

редактирование (2):

Я нашел решение, используя WriteableBitmap:

void camera_FrameReceived(IntPtr info, IntPtr frame) 
{
    if (VideoImageControlToUpdate == null)
    {
        throw new NullReferenceException("VideoImageControlToUpdate must be set before frames can be processed");
    }

    int width, height, size;
    unsafe
    {
        BITMAPINFOHEADER* b = (BITMAPINFOHEADER*)info;

        width = b->biWidth;
        height = b->biHeight;
        size = (int)b->biSizeImage;
    }
    if (height < 0) height = -height;

        //Warp space-time
        VideoImageControlToUpdate.Dispatcher.Invoke((Action)delegate {
        try
        {
            if (VideoImageControlToUpdateSource == null)
            {
                VideoImageControlToUpdateSource =
                    new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, BitmapPalettes.Gray256);
            }
            else if (VideoImageControlToUpdateSource.PixelHeight != height ||
                     VideoImageControlToUpdateSource.PixelWidth != width)
            {
                VideoImageControlToUpdateSource =
                    new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, BitmapPalettes.Gray256);
            }

            VideoImageControlToUpdateSource.Lock();

            VideoImageControlToUpdateSource.WritePixels(
                new Int32Rect(0, 0, width, height),
                frame,
                size,
                width);

            VideoImageControlToUpdateSource.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
            VideoImageControlToUpdateSource.Unlock();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    });
}

В приведенном выше примере VideoImageControlToUpdate - это WPF Image control.

Для большей скорости я считаю, что элемент VideoRendererElement, найденный в codeplex, работает быстрее.

1 Ответ

0 голосов
/ 14 августа 2009

Лучший способ: WriteableBitmap.WritePixels (..., источник IntPtr, ...)

Самый быстрый способ: Используйте WIC и все операции в неуправляемой памяти IntPtr. Но зачем вообще использовать WPF в этом случае? Рассмотрите возможность использования наложения DirectX, если требуется такая производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...