/// <summary> /// Reads the image source and save the extracted images to the specified folder. /// </summary> /// <param name="imageSource">Image stream reader.</param> /// <param name="outputDir">Output directory.</param> /// <param name="fileNameFormat">Image file name format.</param> /// <param name="onFrameCompletition">Progress function executed after a frame is saved.</param> public static void SaveFrames(this ImageStreamReader imageSource, string outputDir, string fileNameFormat = "img-{0:000}.png", Action <float> onFrameCompletition = null) { if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } if (imageSource.CanSeek) { imageSource.Seek(0, SeekOrigin.Begin); } var idx = 0; foreach (var frame in imageSource) //use video stream as IEnumerable<IImage> (must support seek operation) { if (frame != null) //some videos skip key frames (discard those frames) { var path = Path.Combine(outputDir, String.Format(fileNameFormat, idx)); ImageIO.TrySave(frame, path); //TODO-noncritical: add compression options } if (onFrameCompletition != null) { onFrameCompletition((float)(idx + 1) / imageSource.Length); } idx++; } }
/// <summary> /// Reads an image from the stream. /// </summary> /// <param name="image">Read image.</param> /// <returns>True if the reading operation was successful, false otherwise.</returns> protected override bool ReadInternal(out IImage image) { lock (syncObj) { image = default(IImage); if (this.Position >= this.Length) { return(false); } image = ImageIO.LoadUnchanged(FileInfos[currentFrame].FullName); currentFrame++; } return(true); }