/// <summary> /// Lazily enumerate the images that will end up in the final file. /// Return fully painted bitmaps ready for saving in the output. /// In case of early cancellation or error, the caller must dispose the bitmap to avoid a leak. /// </summary> private IEnumerable <Bitmap> FrameEnumerator(SavingSettings settings) { // When we move to a full hierarchy of exporters classes, // each one will implement its own logic to transform the frames from // the working zone (or just the kf) to the final list of bitmaps to save. foreach (VideoFrame vf in videoReader.FrameEnumerator()) { if (vf == null) { log.Error("Working zone enumerator yield null."); yield break; } Bitmap bmp = vf.Image.CloneDeep(); long ts = vf.Timestamp; Graphics g = Graphics.FromImage(bmp); long keyframeDistance = settings.ImageRetriever(g, bmp, ts, settings.FlushDrawings, settings.KeyframesOnly); if (!settings.KeyframesOnly || keyframeDistance == 0) { int duplication = settings.PausedVideo && keyframeDistance == 0 ? settings.KeyframeDuplication : settings.Duplication; for (int i = 0; i < duplication; i++) { yield return(bmp); } } bmp.Dispose(); } }
public static void ResetSettings() { BinaryFormatter binform = new BinaryFormatter(); string filepath = Application.persistentDataPath + "/Settings.pexo"; SavingSettings tmp = new SavingSettings(); tmp.MusicVolume = 1f; tmp.GraphicsQuality = 0; FileStream savefile = File.Create(filepath); binform.Serialize(savefile, tmp); savefile.Close(); AudioListener.volume = MusicVolume; }
static public void addPropertiesLabels(byte[] image, string name, string value, string elemName, Font elementFont, Color elementForeColor) { SavingSettings setting = new SavingSettings() { SettingName = name, SettingValue = value, SettingImage = image, ElementName = elemName, Font = elementFont, Color = elementForeColor }; if (elemName == "Panel") { savingImages.Add(JsonConvert.SerializeObject(setting)); } else if (elemName == "Label") { savingString.Add(JsonConvert.SerializeObject(setting)); } }
private void DoSave(string filePath, double frameInterval, bool flushDrawings, bool keyframesOnly, bool pausedVideo, ImageRetriever imageRetriever) { SavingSettings s = new SavingSettings(); s.Section = videoReader.WorkingZone; s.File = filePath; s.InputFrameInterval = frameInterval; s.FlushDrawings = flushDrawings; s.KeyframesOnly = keyframesOnly; s.PausedVideo = pausedVideo; s.ImageRetriever = imageRetriever; formProgressBar = new formProgressBar(true); formProgressBar.Cancel = Cancel_Asked; bgWorkerSave.RunWorkerAsync(s); formProgressBar.ShowDialog(); }
/// <summary> /// Lazily enumerate the images that will end up in the final file. /// Return fully painted bitmaps ready for saving in the output. /// In case of early cancellation or error, the caller must dispose the bitmap to avoid a leak. /// </summary> private IEnumerable <Bitmap> EnumerateImages(SavingSettings settings) { Bitmap output = null; // Enumerates the raw frames from the video (at original video size). foreach (VideoFrame vf in videoReader.FrameEnumerator()) { if (vf == null) { log.Error("Working zone enumerator yield null."); if (output != null) { output.Dispose(); } yield break; } if (output == null) { output = new Bitmap(vf.Image.Width, vf.Image.Height, vf.Image.PixelFormat); } bool onKeyframe = settings.ImageRetriever(vf, output); bool savable = onKeyframe || !settings.KeyframesOnly; if (savable) { int duplication = settings.PausedVideo && onKeyframe ? settings.KeyframeDuplication : settings.Duplication; for (int i = 0; i < duplication; i++) { yield return(output); } } } if (output != null) { output.Dispose(); } }
public static void LoadSettings() { string filepath = Application.persistentDataPath + "/Settings.pexo"; BinaryFormatter binform = new BinaryFormatter(); if (!File.Exists(filepath)) { GraphicsQuality = 0; MusicVolume = 1f; } else { FileStream savefile = File.Open(filepath, FileMode.Open); SavingSettings tmp = (SavingSettings)binform.Deserialize(savefile); savefile.Close(); GraphicsQuality = tmp.GraphicsQuality; MusicVolume = tmp.MusicVolume; AudioListener.volume = MusicVolume; } }
private void bgWorkerSave_DoWork(object sender, DoWorkEventArgs e) { Thread.CurrentThread.Name = "Saving"; BackgroundWorker bgWorker = sender as BackgroundWorker; if (!(e.Argument is SavingSettings)) { saveResult = SaveResult.UnknownError; e.Result = 0; return; } SavingSettings settings = (SavingSettings)e.Argument; if (settings.ImageRetriever == null || settings.InputFrameInterval < 0 || bgWorker == null) { saveResult = SaveResult.UnknownError; e.Result = 0; return; } try { log.DebugFormat("Saving selection [{0}]->[{1}] to: {2}", settings.Section.Start, settings.Section.End, Path.GetFileName(settings.File)); // TODO it may actually make more sense to split the saving methods for regular // save, paused video and diaporama. It will cause inevitable code duplication but better encapsulation and simpler algo. // When each save method has its own class and UI panel, it will be a better design. if (!settings.PausedVideo) { // Take special care for slowmotion, the frame interval can not go down indefinitely. // Use frame duplication when under 8fps. settings.Duplication = (int)Math.Ceiling(settings.InputFrameInterval / 125.0); settings.KeyframeDuplication = settings.Duplication; settings.OutputFrameInterval = settings.InputFrameInterval / settings.Duplication; if (settings.KeyframesOnly) { settings.EstimatedTotal = metadata.Count * settings.Duplication; } else { settings.EstimatedTotal = videoReader.EstimatedFrames * settings.Duplication; } } else { // For paused video, slow motion is not supported. // InputFrameInterval will have been set to a multiple of the original frame interval. settings.Duplication = 1; settings.KeyframeDuplication = (int)(settings.InputFrameInterval / metadata.UserInterval); settings.OutputFrameInterval = metadata.UserInterval; long regularFramesTotal = videoReader.EstimatedFrames - metadata.Count; long keyframesTotal = metadata.Count * settings.KeyframeDuplication; settings.EstimatedTotal = regularFramesTotal + keyframesTotal; } log.DebugFormat("interval:{0}, duplication:{1}, kf duplication:{2}", settings.OutputFrameInterval, settings.Duplication, settings.KeyframeDuplication); videoReader.BeforeFrameEnumeration(); IEnumerable <Bitmap> images = EnumerateImages(settings); VideoFileWriter w = new VideoFileWriter(); string formatString = FilenameHelper.GetFormatString(settings.File); saveResult = w.Save(settings, videoReader.Info, formatString, images, bgWorker); videoReader.AfterFrameEnumeration(); } catch (Exception exp) { saveResult = SaveResult.UnknownError; log.Error("Unknown error while saving video."); log.Error(exp.StackTrace); } e.Result = 0; }
/// <summary> /// Saves all of the settings on this page to storage. /// </summary> public override void SaveSettingsToStorage() { SavingSettings?.Invoke(this, EventArgs.Empty); base.SaveSettingsToStorage(); }