如何从 C# 中的图像目录创建视频?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/251467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:58:19  来源:igfitidea点击:

How can I create a video from a directory of images in C#?

c#directshowmediamultimediawmv

提问by JP Richardson

I have a directory of bitmaps that are all of the same dimension. I would like to convert these bitmaps into a video file. I don't care if the video file (codec) is wmv or avi. My only requirement is that I specify the frame rate. This does not need to be cross platform, Windows (Vista and XP) only. I have read a few things about using the Windows Media SDK or DirectShow, but none of them are that explicit about providing code samples.

我有一个所有尺寸相同的位图目录。我想将这些位图转换为视频文件。我不在乎视频文件(编解码器)是 wmv 还是 avi。我唯一的要求是指定帧速率。这不需要是跨平台的,仅适用于 Windows(Vista 和 XP)。我已经阅读了一些关于使用 Windows Media SDK 或 DirectShow 的内容,但它们都没有明确提供代码示例。

Could anyone provide some insight, or some valuable resources that might help me to do this in C#?

任何人都可以提供一些见解或一些有价值的资源来帮助我在 C# 中做到这一点吗?

采纳答案by crftr

At the risk of being voted down, I'll offer a possible alternative option-- a buffered Bitmap animation.

冒着被否决的风险,我将提供一个可能的替代选项——缓冲位图动画。

double framesPerSecond;
Bitmap[] imagesToDisplay;     // add the desired bitmaps to this array
Timer playbackTimer;

int currentImageIndex;
PictureBox displayArea;

(...)

currentImageIndex = 0;
playbackTimer.Interval = 1000 / framesPerSecond;
playbackTimer.AutoReset = true;
playbackTimer.Elapsed += new ElapsedEventHandler(playbackNextFrame);
playbackTimer.Start();

(...)

void playbackNextFrame(object sender, ElapsedEventArgs e)
{
    if (currentImageIndex + 1 >= imagesToDisplay.Length)
    {
            playbackTimer.Stop();

            return;
    }

    displayArea.Image = imagesToDisplay[currentImageIndex++];
}

An approach such as this works well if the viewing user has access to the images, enough resources to keep the images in memory, doesn't want to wait for a video to encode, and there may exist a need for different playback speeds.

如果查看用户可以访问图像,有足够的资源将图像保存在内存中,不想等待视频编码,并且可能需要不同的播放速度,则这种方法很有效。

...just throwing it out there.

……只是把它扔在那里。

回答by Aleris

You can use the AVI* from avifil32 library, there is an example here (not tried):
http://www.adp-gmbh.ch/csharp/mandelbrot/index.html

您可以使用 avifil32 库中的 AVI*,这里有一个示例(未尝试):http:
//www.adp-gmbh.ch/csharp/mandelbrot/index.html

This might be of interest for you:
http://bytescout.com/swfslideshowscout_example_c_sharp.html
(make flash slideshow from JPG images using C#)

这可能对您感兴趣:
http: //bytescout.com/swfslideshowscout_example_c_sharp.html
(使用 C# 从 JPG 图像制作 Flash 幻灯片)

回答by GvS

I have not tried it, but Windows Movie Makerhas an API, and XML file format you can use.

我还没有尝试过,但Windows Movie Maker有一个 API 和您可以使用的 XML 文件格式。

回答by Stu Mackellar

An ideal technology to achieve what you want is DirectShow Editing Services. However, if this is a one-off project then I wouldn't bother - the learning curve can be quite steep.

实现您想要的理想技术是DirectShow 编辑服务。但是,如果这是一个一次性项目,那么我不会打扰 - 学习曲线可能非常陡峭。

There's not much in the way of DES sample code available, although there's plenty of general DirectShow samples both within and outside MSDN. For your purposes I'd recommend starting herefor a basic explanation of using still images as a video source.

尽管在 MSDN 内部和外部都有大量的通用 DirectShow 示例,但可用的 DES 示例代码的方式并不多。出于您的目的,我建议您从这里开始了解使用静止图像作为视频源的基本解释。

回答by loraderon

You can use Splicerto do this.

您可以使用Splicer来执行此操作。

Please see example 3 at http://www.codeplex.com/splicer/Wiki/View.aspx?title=News%20Feeds&referringTitle=Home

请参阅http://www.codeplex.com/splicer/Wiki/View.aspx?title=News%20Feeds&referringTitle=Home 上的示例 3

Edit:

编辑:

using (ITimeline timeline = new DefaultTimeline(25))
{
    IGroup group = timeline.AddVideoGroup(32, 160, 100);

    ITrack videoTrack = group.AddTrack();
    IClip clip1 = videoTrack.AddImage("image1.jpg", 0, 2);
    IClip clip2 = videoTrack.AddImage("image2.jpg", 0, 2);
    IClip clip3 = videoTrack.AddImage("image3.jpg", 0, 2);
    IClip clip4 = videoTrack.AddImage("image4.jpg", 0, 2);

    double halfDuration = 0.5;

    group.AddTransition(clip2.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true);
    group.AddTransition(clip2.Offset, halfDuration, StandardTransitions.CreateFade(), false);

    group.AddTransition(clip3.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true);
    group.AddTransition(clip3.Offset, halfDuration, StandardTransitions.CreateFade(), false);

    group.AddTransition(clip4.Offset - halfDuration, halfDuration, StandardTransitions.CreateFade(), true);
    group.AddTransition(clip4.Offset, halfDuration, StandardTransitions.CreateFade(), false);

    ITrack audioTrack = timeline.AddAudioGroup().AddTrack();

    IClip audio =
        audioTrack.AddAudio("soundtrack.wav", 0, videoTrack.Duration);

    audioTrack.AddEffect(0, audio.Duration,
                        StandardEffects.CreateAudioEnvelope(1.0, 1.0, 1.0, audio.Duration));

    using (
        WindowsMediaRenderer renderer =
            new WindowsMediaRenderer(timeline, "output.wmv", WindowsMediaProfiles.HighQualityVideo))
    {
        renderer.Render();
    }
}