Как я могу создать видео файл из отдельных изображений в проекте ac # - PullRequest
0 голосов
/ 07 июня 2019

Я хотел бы создать видеофайл из списка в c #, который может быть в любом формате, который может открыть медиаплеер.

Я пробовал Aforge и Avi-упаковщик файлов, но, к сожалению, они работают только в x86и у меня довольно много зависимостей, так что я не могу изменить тип проекта.Таким образом, он должен быть x64.

Все мои растровые изображения находятся в списке (который составляет около 50 или около того) public List tv_ImageData = new List ();

Я новичок в c # иЯ не знаю, как много.Я гуглил и не мог найти решение.Буду признателен, если кто-нибудь укажет мне правильное направление (или библиотеку).

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

После некоторого смешения с SharpAvi я решил свою проблему.У меня был список с именем

List<ushort[]> tv_data = new List<ushort> tv_data();

, который содержал кадры в виде необработанных данных (значения в диапазоне 0-255).Я попытался использовать пример, предоставленный документацией, но это дало мне преимущество в avi (думаю, это потому, что SharpAvi ожидает битовые карты DIB).Поэтому я немного его изменил и немного позаимствовал ( Как создать растровое изображение из байтового массива? ). Вверх получим рабочее решение.

Вот моя функция:

using SharpAvi;
using SharpAvi.Output;

Возможно, это не лучший способ сделать это, но это работает.Надеюсь, кто-нибудь найдет это полезным.

private void SaveAsVideo(object sender, RoutedEventArgs e)
{
    if (loadedFileName != "")
    {
        try
        {
            var writer = new AviWriter(string.Format("{0}.avi", fullPath))
            {
                FramesPerSecond = (decimal)VI.FrameRate,
                EmitIndex1 = true
            };
            var stream = writer.AddVideoStream();
            stream.Width = (int)VI.VideoWidth;
            stream.Height = (int)VI.VideoHeight;
            stream.Codec = KnownFourCCs.Codecs.Uncompressed;
            stream.BitsPerPixel = BitsPerPixel.Bpp8;

            var frameData = new byte[stream.Width * stream.Height];
            int frameNo = 0;
            foreach (ushort[] data in tv_Data)
            {
                byte[] byteData = tv_Data.ElementAt(frameNo);
                byte[] newbytes = PadLines(byteData, stream.Height, stream.Width);
                stream.WriteFrame(true, newbytes, 0, frameData.Length);
                frameNo++;
            }
            writer.Close();
            MessageBox.Show("Video file saved.");
        }
        catch (Exception ex)
        {
            MessageBox.Show(string.Format("Failed to save video. \n {0}", ex.Message));
        }
    }
}
static byte[] PadLines(byte[] bytes, int rows, int columns)
{
    int currentStride = columns;
    int newStride = columns;
    byte[] newBytes = new byte[newStride * rows];
    byte[] tempBytes = new byte[newStride];

    for (int i = 0; i < rows; i++)
    {
        Buffer.BlockCopy(bytes, currentStride * i, tempBytes, 0, currentStride);
        Array.Reverse(tempBytes);
        Buffer.BlockCopy(tempBytes, 0, newBytes, newStride * i, currentStride);
    }
    Array.Reverse(newBytes);
    return newBytes;
}
0 голосов
/ 07 июня 2019

(я чувствую, что это будет лучше в качестве комментария, но у меня пока нет на это репутации. Извините, если это плохая практика!)

Поскольку ваша единственная проблема с AForge заключается в том, что он скомпилирован для x86, я упомяну, что, похоже, вы можете самостоятельно перекомпилировать его для цели x64.

https://github.com/andrewkirillov/AForge.NET

Быстрый поиск нашел эту ссылку на перекомпиляцию AForge, включающую 64-битную версию:

https://archive.codeplex.com/?p=aforgeffmpeg

Я бы не знал, актуально ли это или нет, поэтому я мог бы рекомендовать составить его самостоятельно.

Надеюсь, это поможет!

...