C# 如何循环所有双位置以将所有帧保存到硬盘?

C# 如何循环所有双位置以将所有帧保存到硬盘?,c#,C#,我使用FrameGrabber.cs,并添加了它的dll作为参考:JockerSoft.Media.dll和Interop.qedit 现在,在构造器中的Form1代码中,我试图检索所有处于其位置的帧,并将每个帧保存到硬盘上的新位图文件中,但我不知道如何执行此操作 我不知道如何循环所有帧/双[]位置,我还想了解关于有多少帧的信息,我可以得到帧速率17.8 我想获得所有帧的列表/数组,然后将每个帧保存到硬盘,然后对帧进行另一次操作 是我从中获得示例的站点。试图查看那里和源代码,但不知道如何做到这一

我使用FrameGrabber.cs,并添加了它的dll作为参考:JockerSoft.Media.dll和Interop.qedit

现在,在构造器中的Form1代码中,我试图检索所有处于其位置的帧,并将每个帧保存到硬盘上的新位图文件中,但我不知道如何执行此操作

我不知道如何循环所有帧/双[]位置,我还想了解关于有多少帧的信息,我可以得到帧速率17.8

我想获得所有帧的列表/数组,然后将每个帧保存到硬盘,然后对帧进行另一次操作

是我从中获得示例的站点。试图查看那里和源代码,但不知道如何做到这一点

**我在designer中也有一个trackBar1,我希望能够滚动浏览所有的帧,但效果也不好

这是我的Form1代码,工作不好,我只能得到一帧

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExtractFrames.Properties;
using ExtractFrames;
using JockerSoft.Media;
using JockerSoft;
using Interop.qedit;
using Interop;
using System.Runtime.InteropServices;

namespace ExtractFrames
{
    public partial class Form1 : Form
    {
        double x;
        string sf;
        double[] streamDouble ;
        string strVideoFile;
        public Form1()
        {
            InitializeComponent();
            sf = @"d:\Frames\";
            strVideoFile = @"d:\My Movie.wmv";
            for (int x = 0; x < 40; x++)
            {
                streamDouble = new double[x];
                SaveFramesFromVideo(strVideoFile, streamDouble, sf + x.ToString("D6") + ".bmp");
            }
            //getFrameRate();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private  void getFrameRate()
        {
            // Get framerate
            MediaDet md = new MediaDet();
            md.Filename = strVideoFile;
            //md.CurrentStream = 0;                     // choose the video stream
            x = md.FrameRate;
            double i = md.StreamLength;

        }

        public static void SaveFramesFromVideo(string videoFile, double[] positions, string outputBitmapFiles)
        {
            if (videoFile == null)
                throw new ArgumentNullException("videoFile");

            double streamLength;

            IMediaDet mediaDet = null;
            try
            {
                _AMMediaType mediaType;
                if (openVideoStream(videoFile, out mediaDet, out mediaType))
                {
                    streamLength = mediaDet.StreamLength;
                    Size target = getVideoSize(mediaType);
                    int iteration = 0;
                    foreach (double position in positions)
                    {
                        iteration++;
                        string outputBitmapFile = string.Format(outputBitmapFiles, iteration);
                        mediaDet.WriteBitmapBits(position, target.Width, target.Height, outputBitmapFile);
                    }
                    return;
                }
            }
            catch (COMException ex)
            {
                throw new InvalidVideoFileException();
            }
            finally
            {
                if (mediaDet != null)
                    Marshal.ReleaseComObject(mediaDet);
            }

            throw new InvalidVideoFileException("No video stream was found");
        }


        private static Size getVideoSize(_AMMediaType mediaType)
        {
            WinStructs.VIDEOINFOHEADER videoInfo = (WinStructs.VIDEOINFOHEADER)Marshal.PtrToStructure(mediaType.pbFormat, typeof(WinStructs.VIDEOINFOHEADER));

            return new Size(videoInfo.bmiHeader.biWidth, videoInfo.bmiHeader.biHeight);
        }

        private static Size scaleToFit(Size target, Size original)
        {
            if (target.Height * original.Width > target.Width * original.Height)
                target.Height = target.Width * original.Height / original.Width;
            else
                target.Width = target.Height * original.Width / original.Height;

            return target;
        }
        private static Size scaleToFitSmart(Size target, Size original)
        {
            target = scaleToFit(target, original);

            if (target.Width > original.Width || target.Height > original.Height)
                return original;

            return target;
        }


        private static bool openVideoStream(string videoFile, out IMediaDet mediaDet, out _AMMediaType aMMediaType)
        {
            mediaDet = new MediaDet();

            //loads file
            mediaDet.Filename = videoFile;

            //gets # of streams
            int streamsNumber = mediaDet.OutputStreams;

            //finds a video stream
            for (int i = 0; i < streamsNumber; i++)
            {
                mediaDet.CurrentStream = i;
                _AMMediaType mediaType = mediaDet.StreamMediaType;

                if (mediaType.majortype == JockerSoft.Media.MayorTypes.MEDIATYPE_Video)
                {
                    //video stream found
                    aMMediaType = mediaType;
                    return true;
                }
            }

            //no video stream found
            Marshal.ReleaseComObject(mediaDet);
            mediaDet = null;
            aMMediaType = new _AMMediaType();
            return false;
        }



    }


}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用提取器框架。属性;
使用提取器框架;
使用JockerSoft.Media;
使用JockerSoft;
使用Interop.qedit;
使用互操作;
使用System.Runtime.InteropServices;
命名空间提取框架
{
公共部分类Form1:Form
{
双x;
字符串sf;
双[]流双;
字符串strvideo文件;
公共表格1()
{
初始化组件();
sf=@“d:\Frames\”;
strVideoFile=@“d:\My Movie.wmv”;
对于(int x=0;x<40;x++)
{
streamDouble=新的双精度[x];
SaveFramesFromVideo(strVideo文件、streamDouble、sf+x.ToString(“D6”)+“.bmp”);
}
//getFrameRate();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
}
私有void getFrameRate()
{
//获取帧率
MediaDet md=新的MediaDet();
md.Filename=strVideoFile;
//md.CurrentStream=0;//选择视频流
x=md.FrameRate;
双i=md.StreamLength;
}
public static void SaveFramesFromVideo(字符串视频文件、双[]位置、字符串输出位图文件)
{
如果(视频文件==null)
抛出新的异常(“视频文件”);
双流长;
IMediaDet mediaDet=null;
尝试
{
_AMMediaType mediaType;
if(openVideoStream(视频文件、输出媒体数据、输出媒体类型))
{
streamLength=mediaDet.streamLength;
大小目标=getVideoSize(mediaType);
int迭代=0;
foreach(双位置中的双位置)
{
迭代++;
string outputBitmapFile=string.Format(outputBitmapFiles,迭代);
mediaDet.WriteBitmapBits(位置、目标宽度、目标高度、输出位图文件);
}
返回;
}
}
捕获(COMException ex)
{
抛出新的InvalidVideoFileException();
}
最后
{
if(mediaDet!=null)
发布对象元帅(mediaDet);
}
抛出新的InvalidVideoFileException(“未找到视频流”);
}
私有静态大小getVideoSize(\u AMMediaType mediaType)
{
WinStructs.VIDEOINFOHEADER videoInfo=(WinStructs.VIDEOINFOHEADER)Marshal.PtrToStructure(mediaType.pbFormat,typeof(WinStructs.VIDEOINFOHEADER));
返回新大小(videoInfo.bmiHeader.biWidth、videoInfo.bmiHeader.biHeight);
}
专用静态尺寸缩放(目标尺寸、原始尺寸)
{
if(target.Height*original.Width>target.Width*original.Height)
target.Height=target.Width*original.Height/original.Width;
其他的
target.Width=target.Height*original.Width/original.Height;
回报目标;
}
专用静态尺寸scaleToFitSmart(尺寸目标,原始尺寸)
{
目标=缩放拟合(目标,原始);
if(target.Width>original.Width | | target.Height>original.Height)
归还原件;
回报目标;
}
私有静态bool openVideoStream(字符串视频文件,out-IMediaDet-mediaDet,out\u-AMMediaType-AMMediaType)
{
mediaDet=新的mediaDet();
//加载文件
mediaDet.Filename=视频文件;
//获取#个流
int streamsNumber=mediaDet.OutputStreams;
//查找视频流
对于(int i=0;i
方法
SaveFramesFromVideo()
需要一个以秒为单位填充文件中百分比位置的双数组-因为您不知道这与视频长度的关系,所以不能单独使用帧速率。但是,您可以将每一个完整百分比的帧保存到
var streamDouble = new double[1];
for (int x = 0; x < 100; x++)
{
    streamDouble[0] = x;
    SaveFramesFromVideo(strVideoFile, streamDouble, sf + x.ToString("D6") + ".bmp");
}
AsfFile asfFile = new AsfFile(@"D:\samples\sample.wmv");
AsfFileProperties fileProperties = asfFile.GetAsfObject<AsfFileProperties>();
TimeSpan duration = TimeSpan.FromTicks((long)fileProperties.PlayDuration) - TimeSpan.FromMilliseconds(fileProperties.Preroll);

var streamProps = asfFile.GetAsfObjects<AsfExtendedStreamProperties>()
                         .SingleOrDefault(x => x.StreamNumber == asfFile.PacketConfiguration.AsfVideoStreamId);

double timePerFrame = streamProps.AvgTimePerFrame / (double) 10000000 ;

double offset = 0;
while (offset < duration.TotalSeconds)
{
    using (var bitmap = AsfImage.FromFile(@"D:\samples\sample.wmv").AtOffset(offset))
    {
        if(bitmap!=null)
            bitmap.Save(string.Format(@"d:\Frames\{0}.jpg", offset.ToString("N")), ImageFormat.Jpeg);
    }
    offset += timePerFrame;
}