C# Bitmap в AVI/WMV со сжатием

Прелюдия:

Я собираюсь предварить это тем, что я изучал C # в свободное время на работе, и что я смотрел на код в течение целых двух дней, пытаясь понять эту проблему. Я разрабатываю некоторое программное обеспечение для использования с визуализатором, который подключается через USB к стандартному настольному ПК, программное обеспечение обнаруживает устройство захвата и загружает кадры в растровое изображение с помощью нового события кадра, затем это отображается в «окне изображения» как видеотрансляция в прямом эфире. Проблема заключается в том, чтобы включить возможность записи потока и сохранения в файл, предпочтительно в WMV или сжатый AVI.

Что было испробовано:

Я рассмотрел и рассмотрел следующее:

SharpAVI — похоже, не удается заставить это сжимать или сохранять кадры должным образом, так как в основном он просматривает существующие файлы AVI.

AForge.Video.VFW. Файлы AVI можно создавать, но они слишком велики для использования из-за ограничений на пользовательские области лиц, которые будут использовать это программное обеспечение.

AForge.Video.FFMPEG. Опять же, из-за соображений тех, кто использует это программное обеспечение, я не могу иметь неуправляемые DLL в выходной папке с исполняемым файлом, и, к сожалению, эта конкретная DLL не может быть правильно скомпилирована с помощью Costura. Фоди.

Обертка библиотеки AVIFile (из проекта кода). Опять же, похоже, не удается заставить это правильно сжимать поток из растровых изображений из событий нового кадра.

DirectShow — похоже, я использую C++ и, к сожалению, в настоящее время не могу этого сделать.

Соответствующие фрагменты кода:

Текущие ссылки:

using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Resources;
using System.Drawing.Imaging;
using System.IO;
//Aforge Video DLL's
using AForge.Video;
using AForge.Video.VFW;
using AForge.Video.DirectShow;
//Aforge Image DLL's
using AForge.Imaging;
using AForge.Imaging.Formats;
using AForge.Imaging.Filters;
//AviLibrary
using AviFile;

Глобальные переменные:

    #region Global Variables

    private FilterInfoCollection CaptureDevice; // list of available devices
    private VideoCaptureDevice videoSource;
    public System.Drawing.Image CapturedImage;

    bool toggleMic = false;

    bool toggleRec = false;
    //aforge
    AVIWriter aviWriter;
    Bitmap image;


    #endregion

Код для отображения потока

    #region Displays the Stream

    void videoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        picBoxStream.SizeMode = PictureBoxSizeMode.Zoom;
        picBoxStream.Image = (Bitmap)eventArgs.Frame.Clone();// clones the bitmap


        if (toggleRec == true)
        {
            image = (Bitmap)eventArgs.Frame.Clone();
            aviWriter.AddFrame(image);
        }
    }

    #endregion

Текущий код для записи потока

    #region Record Button

    private void btnRecord_Click(object sender, EventArgs e)
    {
        if (toggleRec == false)
        {
            saveAVI = new SaveFileDialog();
            saveAVI.Filter = "AVI Files (*.avi)|*.avi";

            if (saveAVI.ShowDialog() == DialogResult.OK)
            {
                aviWriter = new AVIWriter();
                aviWriter.Open(saveAVI.FileName, 1280, 720);

                toggleRec = true;
                Label lblRec = new Label();
            }

        }
        else if (toggleRec == true)
        {
            aviWriter.Close();
            toggleRec = false;
        }
    }

    #endregion

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

Заранее спасибо.

ИЗМЕНЕНИЕ: 2019:

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


person Digitalsa1nt    schedule 23.04.2015    source источник
comment
Вы рассматривали низкотехнологичное решение этой проблемы, например, использование снимка экрана на выделенном прямоугольнике экрана?   -  person BrokenGlass    schedule 19.05.2015
comment
Я предполагаю, что это будет включать использование стороннего программного обеспечения? Основная проблема, с которой я столкнулся, заключается в том, что в идеале все функции должны быть в одном приложении - в настоящее время я рассматриваю возможность сжатия изображений, когда они являются растровыми изображениями в памяти.   -  person Digitalsa1nt    schedule 24.05.2015


Ответы (2)


та же проблема, которую я только что решил :) вот мой код, как использовать dll библиотеки AviFile для создания avi-файла :)

    private void MakeAvi(List<Bitmap> maps)
    {
        AviManager mana = new AviManager("local.avi", false);

        //false means do not show the diag of the Compression 
        //21 means the fps of the video
        //maplist[0] cover of the video  the maplist is the val you should insert 
        VideoStream avistream = mana.AddVideoStream(false, 21, maplist[0]);

        for (int i = 1; i < maps.Count; i++)
        {
            avistream.AddFrame(maplist[i]);
        }

        mana.Close();
        MessageBox.Show("AddOk");
    }
person Bruce Done    schedule 20.08.2015
comment
Спасибо за ответ, я просто собираюсь взглянуть на ваш ответ и посмотреть, смогу ли я воспроизвести его, но просто чтобы проверить, что мы передаем в переменную maplist (я предполагаю, что переменная maplist другой список‹Растровое изображение›? - person Digitalsa1nt; 21.08.2015
comment
В порядке. Я прошел и опробовал метод, описанный выше, и, хотя он успешно создает файл AVI, к сожалению, он не сжимает размеры растрового изображения, поэтому короткий 30-секундный видеофайл по-прежнему занимает 100 с лишним мегабайт. - person Digitalsa1nt; 21.08.2015
comment
да, это проблема, которую я просто не могу решить, если вы хотите сжать файл, вы должны вызвать функцию следующим образом: VideoStream avistream = mana.AddVideoStream(yes, 21, maplist[0]); затем перед созданием видеопотока он покажет диалоговое окно для выбора способа сжатия видео, но я просто не могу найти способ не показывать этот диалог и сжимать видео - person Bruce Done; 26.08.2015
comment
Привет, я только что нашел способ установить параметры сжатия, просто обратитесь к этому: msdn .microsoft.com/en-us/magazine/hh580739.aspx - person Bruce Done; 26.08.2015

person    schedule
comment
Я постараюсь попробовать это завтра или в пятницу, и я отмечу это как ответ, если это поможет, спасибо за добавление этого. - person Digitalsa1nt; 19.07.2016