Последовательность изображений для видеоstreamа?

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

Я хочу реализовать свою функциональность на C #!

Вот что я не буду делать:

/*Pseudo code*/ void CreateVideo(List imageSequence, long durationOfEachImageMs, string outputVideoFileName, string outputFormat) { // Info: imageSequence.Count will be > 30 000 images // Info: durationOfEachImageMs will be < 300 ms if (outputFormat = "mpeg") { } else if (outputFormat = "avi") { } else { } //Save video file do disk } 

Я знаю, что есть проект Splicer ( http://splicer.codeplex.com/ ), но я не могу найти подходящую документацию или ясные примеры, которые я могу выполнить ( это примеры, которые я нашел).

Самый близкий, который я хочу сделать, который я нахожу здесь в CodePlex, таков: как я могу создать видео из каталога изображений на C #?

Я также прочитал несколько streamов о ffmpeg (например, это: C # и FFmpeg предпочтительно без команд оболочки, и это: конвертировать последовательность изображений с помощью ffmpeg ), но я не нахожу никого, кто мог бы помочь мне с моей проблемой, и я не думаю, что ffmpeg – command-line-style – лучшее решение для меня (из-за количества изображений).

Я считаю, что я могу использовать Splicer- проект каким-то образом (?).

В моем случае примерно около 30 000 изображений, где каждое изображение должно отображаться примерно 200 мс (в видеоstreamе, который я хочу создать).

(Что такое видео? Растения растут …)

Может ли кто-нибудь помочь мне выполнить мою функцию?

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

Я разберу свой ответ на три части:

  • Задний план
  • проблема
  • Решение

Задний план

(этот раздел не важен для решения)

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

Моя настройка оборудования была похожа на общий рисунок: введите описание изображения здесь

На изображениях изображены растущие растения томатов в разных состояниях. Все снимки снимались каждые 1 минуту в дневное время.

 /*pseudo code for taking and storing images*/ while (true) { if (daylight) { //get an image from the camera //store the image as byte array to db } //wait 1 min } 

У меня был очень простой db для хранения изображений, в нем была только одна таблица (таблица ImageSet): введите описание изображения здесь


проблема

Я прочитал много статей о ffmpeg (см. Мой оригинальный вопрос), но я не мог найти, как перейти от коллекции изображений к видео.


Решение

Наконец, я получил рабочее решение! Основная его часть – из проекта с открытым исходным кодом AForge.NET . Короче говоря, вы можете сказать, что AForge.NET – это компьютерное зрение и библиотека искусственного интеллекта на C # . (Если вы хотите получить копию фреймворка, просто возьмите его с http://www.aforgenet.com/ )

В AForge.NET существует этот class VideoFileWriter (class для записи видеофайлов с помощью ffmpeg). Это почти все работало. (Здесь также очень хороший пример)

Это последний class (сокращенный), который я использовал для извлечения и преобразования данных изображения в видео из моей базы данных изображений:

 public class MovieMaker { public void Start() { var startDate = DateTime.Parse("12 Mar 2012"); var endDate = DateTime.Parse("13 Aug 2012"); CreateMovie(startDate, endDate); } /*THIS CODE BLOCK IS COPIED*/ public Bitmap ToBitmap(byte[] byteArrayIn) { var ms = new System.IO.MemoryStream(byteArrayIn); var returnImage = System.Drawing.Image.FromStream(ms); var bitmap = new System.Drawing.Bitmap(returnImage); return bitmap; } public Bitmap ReduceBitmap(Bitmap original, int reducedWidth, int reducedHeight) { var reduced = new Bitmap(reducedWidth, reducedHeight); using (var dc = Graphics.FromImage(reduced)) { // you might want to change properties like dc.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; dc.DrawImage(original, new Rectangle(0, 0, reducedWidth, reducedHeight), new Rectangle(0, 0, original.Width, original.Height), GraphicsUnit.Pixel); } return reduced; } /*END OF COPIED CODE BLOCK*/ private void CreateMovie(DateTime startDate, DateTime endDate) { int width = 320; int height = 240; var framRate = 200; using (var container = new ImageEntitiesContainer()) { //a LINQ-query for getting the desired images var query = from d in container.ImageSet where d.Date >= startDate && d.Date <= endDate select d; // create instance of video writer using (var vFWriter = new VideoFileWriter()) { // create new video file vFWriter.Open("nameOfMyVideoFile.avi", width, height, framRate, VideoCodec.Raw); var imageEntities = query.ToList(); //loop throught all images in the collection foreach (var imageEntity in imageEntities) { //what's the current image data? var imageByteArray = imageEntity.Data; var bmp = ToBitmap(imageByteArray); var bmpReduced = ReduceBitmap(bmp, width, height); vFWriter.WriteVideoFrame(bmpReduced); } vFWriter.Close(); } } } } 

Обновление 2013-11-29 (как это сделать) (Надеюсь, это то, что вы просили @Kiquenet?)

  1. Загрузите AForge.NET Framework со страницы загрузки (загрузите полный ZIP-архив, и вы найдете много интересных решений Visual Studio с проектами, такими как Video, в AForge.NET Framework-2.2.5\Samples folder ...)
  2. Пространство имен: AForge.Video.FFMPEG (из документации )
  3. Сборка: AForge.Video.FFMPEGAForge.Video.FFMPEG.dll ) (из документации ) (вы можете найти это AForge.Video.FFMPEG.dll в AForge.NET Framework-2.2.5\Release )

Если вы хотите создать свое собственное решение , убедитесь, что у вас есть ссылка на AForge.Video.FFMPEG.dll в вашем проекте. Тогда должно быть легко использовать class VideoFileWriter . Если вы перейдете по ссылке к classу, вы найдете очень хороший (и простой пример). В коде они подают VideoFileWriter с Bitmap image в for -loop


Я нашел этот код в образцах slicer, выглядит довольно близко к тому, что вы хотите:

 string outputFile = "FadeBetweenImages.wmv"; using (ITimeline timeline = new DefaultTimeline()) { IGroup group = timeline.AddVideoGroup(32, 160, 100); ITrack videoTrack = group.AddTrack(); IClip clip1 = videoTrack.AddImage("image1.jpg", 0, 2); // play first image for a little while IClip clip2 = videoTrack.AddImage("image2.jpg", 0, 2); // and the next IClip clip3 = videoTrack.AddImage("image3.jpg", 0, 2); // and finally the last IClip clip4 = videoTrack.AddImage("image4.jpg", 0, 2); // and finally the last } double halfDuration = 0.5; // fade out and back in group.AddTransition(clip2.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true); group.AddTransition(clip2.Offset, halfDuration, StandardTransitions.CreateFade(), false); // again group.AddTransition(clip3.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true); group.AddTransition(clip3.Offset, halfDuration, StandardTransitions.CreateFade(), false); // and again group.AddTransition(clip4.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true); group.AddTransition(clip4.Offset, halfDuration, StandardTransitions.CreateFade(), false); // add some audio ITrack audioTrack = timeline.AddAudioGroup().AddTrack(); IClip audio = audioTrack.AddAudio("testinput.wav", 0, videoTrack.Duration); // create an audio envelope effect, this will: // fade the audio from 0% to 100% in 1 second. // play at full volume until 1 second before the end of the track // fade back out to 0% volume audioTrack.AddEffect(0, audio.Duration, StandardEffects.CreateAudioEnvelope(1.0, 1.0, 1.0, audio.Duration)); // render our slideshow out to a windows media file using ( IRenderer renderer = new WindowsMediaRenderer(timeline, outputFile, WindowsMediaProfiles.HighQualityVideo)) { renderer.Render(); } } 

Мне не удалось заставить приведенный выше пример работать. Однако я нашел другую библиотеку, которая работает удивительно хорошо один раз. Попробуйте через NuGet «accord.extensions.imaging.io», затем я написал следующую небольшую функцию:

  private void makeAvi(string imageInputfolderName, string outVideoFileName, float fps = 12.0f, string imgSearchPattern = "*.png") { // reads all images in folder VideoWriter w = new VideoWriter(outVideoFileName, new Accord.Extensions.Size(480, 640), fps, true); Accord.Extensions.Imaging.ImageDirectoryReader ir = new ImageDirectoryReader(imageInputfolderName, imgSearchPattern); while (ir.Position < ir.Length) { IImage i = ir.Read(); w.Write(i); } w.Close(); } 

Он считывает все изображения из папки и выдает видео из них.

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

Эта функция основана на библиотеке Splicer.Net. Постарайтесь понять, как работает эта библиотека. Убедитесь, что ваш fps (кадр в секунду) правильный. Кстати стандартный 24 f / s.

В моем случае у меня 15 изображений, и теперь я хочу, чтобы мне понадобилось 7 секунд видео-> так fps = 2. Fps может варьироваться в зависимости от платформы … или использования разработчика.

 public bool CreateVideo(List bitmaps, string outputFile, double fps) { int width = 640; int height = 480; if (bitmaps == null || bitmaps.Count == 0) return false; try { using (ITimeline timeline = new DefaultTimeline(fps)) { IGroup group = timeline.AddVideoGroup(32, width, height); ITrack videoTrack = group.AddTrack(); int i = 0; double miniDuration = 1.0 / fps; foreach (var bmp in bitmaps) { IClip clip = videoTrack.AddImage(bmp, 0, i * miniDuration, (i + 1) * miniDuration); System.Diagnostics.Debug.WriteLine(++i); } timeline.AddAudioGroup(); IRenderer renderer = new WindowsMediaRenderer(timeline, outputFile, WindowsMediaProfiles.HighQualityVideo); renderer.Render(); } } catch { return false; } return true; } 

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

  • Как сохранить данные двух камер, но не повлиять на скорость их получения?
  • Play Youtube HTML5 встроенное видео в Android WebView
  • Рабочий способ сделать видео с изображений в C #
  • Как использовать эффект медленного движения в определенный интервал времени с помощью ffmpeg
  • Как создать несжатый AVI из серии 1000 изображений PNG с использованием FFMPEG
  • Рисование ограничивающего прямоугольника для выбора области для записи
  • В Google Chrome на Linux, где есть flv, если нет в / tmp?
  • Нажмите на изображение плаката, которое воспроизводится в формате HTML5.
  • Как передать статический видеофайл
  • Видео эскизы в Java
  • WebView и HTML5
  • Давайте будем гением компьютера.