/// <summary> /// Thread method that encodes the list of frames. /// </summary> private void DoWork() { _stage = Stage.Encoding; int countList = _listFrames.Count; #region Show Processing this.Invoke((Action)delegate //Needed because it's a cross thread call. { #region Verifies the minimum size to display the Processing page if (this.Size.Height < 220) { this.Size = new Size(this.Size.Width, 220); } if (this.Size.Width < 400) { this.Size = new Size(400, this.Size.Height); } #endregion this.TransparencyKey = Color.Empty; panelBottom.Visible = false; //Control ctrlParent = panelTransparent; //The Modern one needs to use the panelTransparent. panelTransparent.Controls.Add(Processing.Page = new Processing { Dock = DockStyle.Fill }); Processing.MaximumValue(countList); this.Text = "Screen To Gif - " + Resources.Label_Processing; //Only set the dispose of the Processing page, if needed. if (Settings.Default.showFinished) { Processing.Page.Disposed += processing_Disposed; } Processing.Status(0); Application.DoEvents(); }); #endregion if (Settings.Default.encodingCustom) { #region Ngif encoding int numImage = 0; #region Paint Unchanged Pixels var listToEncode = new List<FrameInfo>(); if (Settings.Default.paintTransparent) { this.Invoke((Action)(delegate { Processing.Defined(Resources.Label_AnalyzingUnchanged); Processing.Status(0); })); listToEncode = ImageUtil.PaintTransparentAndCut(_listFrames, Settings.Default.transparentColor); } #endregion using (_encoder = new AnimatedGifEncoder()) { _encoder.Start(_outputpath); _encoder.SetQuality(Settings.Default.quality); _encoder.SetRepeat(Settings.Default.loop ? (Settings.Default.repeatForever ? 0 : Settings.Default.repeatCount) : -1); // 0 = Always, -1 once this.Invoke((Action)(() => Processing.Defined(Resources.Label_Processing))); #region For Each Frame try { if (Settings.Default.paintTransparent) { #region With Transparency _encoder.SetTransparent(Settings.Default.transparentColor); _encoder.SetDispose(1); //Undraw Method, "Leave". foreach (FrameInfo image in listToEncode) { var bitmapAux = new Bitmap(image.Image); _encoder.SetDelay(_listDelay[numImage]); _encoder.AddFrame(bitmapAux, image.PositionTopLeft.X, image.PositionTopLeft.Y); bitmapAux.Dispose(); numImage++; this.BeginInvoke((Action)(() => Processing.Status(numImage))); } #endregion } else { #region Without foreach (var image in _listFrames) { _encoder.SetDelay(_listDelay[numImage]); _encoder.AddFrame(image.From()); numImage++; this.BeginInvoke((Action)(() => Processing.Status(numImage))); } #endregion } } catch (Exception ex) { LogWriter.Log(ex, "Error in the Ngif encoding."); } #endregion } #region Clean Speciffic Variables listToEncode.Clear(); listToEncode = null; #endregion #endregion } else { #region paint.NET encoding //BUG: The minimum amount of iterations is -1 (no repeat) or 3 (repeat number being 2), if you set repeat as 1, it will repeat 2 times, instead of just 1. //0 = Always, -1 = no repeat, n = repeat number (first shown + repeat number = total number of iterations) var repeat = (Settings.Default.loop ? (Settings.Default.repeatForever ? 0 : Settings.Default.repeatCount) : -1); // 0 = Always, -1 once using (var stream = new MemoryStream()) { using (var encoderNet = new GifEncoder(stream, null, null, repeat)) { for (int i = 0; i < _listFrames.Count; i++) { var bitmapAux = new Bitmap(_listFrames[i]); encoderNet.AddFrame(bitmapAux, 0, 0, TimeSpan.FromMilliseconds(_listDelay[i])); bitmapAux.Dispose(); this.BeginInvoke((Action)(() => Processing.Status(i))); } } stream.Position = 0; try { using (var fileStream = new FileStream(_outputpath, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } catch (Exception ex) { LogWriter.Log(ex, "Error while writing to disk"); } } #endregion } Directory.Delete(_pathTemp, true); #region Finish if (Settings.Default.showFinished) { this.Invoke((Action)delegate { Processing.FinishedState(_outputpath, Resources.btnDone + "!"); this.Text = Resources.Title_EncodingDone; }); //After the user hits "Close", the processing_Disposed is called. To set to the right stage. } else { this.Invoke((Action)delegate { Processing.Page.Dispose(); this.Text = Resources.Title_EncodingDone; this.Invalidate(); //Set again the transparency color this.TransparencyKey = Color.LimeGreen; FinishState(); }); try { _actHook.Start(false, true); //start again the keyboard hook watcher } catch (Exception) { } } #endregion #region Memory Clearing _listFrames.Clear(); _listDelay.Clear(); if (_listFramesEdit != null) { _listFramesEdit.Clear(); _listFramesUndo.Clear(); _listDelayEdit.Clear(); _listDelayUndo.Clear(); } _listFrames = null; _listFramesEdit = null; _listFramesUndo = null; _listDelay = null; _listDelayEdit = null; _listDelayUndo = null; _encoder = null; GC.Collect(); //call the garbage colector to empty the memory #endregion }
/// <summary> /// Thread method that encodes the list of frames. /// </summary> private void DoWork() { int countList = _listBitmap.Count; #region Show Processing var processing = new Processing(); this.Invoke((Action)delegate //Needed because it's a cross thread call. { Control ctrlParent = panelTransparent; panelTransparent.Controls.Add(processing); processing.Dock = DockStyle.Fill; processing.SetMaximumValue(countList); processing.SetStatus(1); }); #endregion if (Settings.Default.STencodingCustom) // if NGif encoding { #region Ngif encoding int numImage = 0; using (_encoder = new AnimatedGifEncoder()) { _encoder.Start(_outputpath); _encoder.SetQuality(Settings.Default.STquality); //BUG: The minimum amount of iterations is -1 (no repeat) or 3 (repeat number being 2), if you set repeat as 1, it will repeat 2 times, instead of just 1. //0 = Always, -1 = no repeat, n = repeat number (first shown + repeat number = total number of iterations) _encoder.SetRepeat(Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once try { foreach (var image in _listBitmap) { this.BeginInvoke((Action)(() => processing.SetStatus(numImage))); _encoder.SetDelay(_listDelay[numImage]); _encoder.AddFrame(image); numImage++; } } catch (Exception ex) { LogWriter.Log(ex, "Ngif encoding."); } } #endregion } else //if paint.NET encoding { #region paint.NET encoding var repeat = (Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once using (var stream = new MemoryStream()) { using (var encoderNet = new GifEncoder(stream, null, null, repeat)) { for (int i = 0; i < _listBitmap.Count; i++) { encoderNet.AddFrame((_listBitmap[i]).CopyImage(), 0, 0, TimeSpan.FromMilliseconds(_listDelay[i])); this.BeginInvoke((Action)(() => processing.SetStatus(i))); } } stream.Position = 0; using (var fileStream = new FileStream(_outputpath, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } #endregion } #region Memory Clearing _listBitmap.Clear(); _listFramesPrivate.Clear(); _listFramesUndo.Clear(); _listDelay.Clear(); _listDelayPrivate.Clear(); _listDelayUndo.Clear(); _listBitmap = null; _listFramesPrivate = null; _listFramesUndo = null; _listDelay = null; _listDelayPrivate = null; _listDelayUndo = null; _encoder = null; GC.Collect(); //call the garbage colector to empty the memory #endregion #region Finish try { this.BeginInvoke((Action)delegate //must use invoke because it's a cross thread call { _caller.Text = Resources.Title_EncodingDone; _stage = (int)Stage.Stoped; panelTransparent.Controls.Clear(); //Clears the processing page. processing.Dispose(); _caller.Invalidate(); FinishState(); _actHook.KeyDown += KeyHookTarget; //Set again the keyboard hook method _actHook.Start(false, true); //start again the keyboard hook watcher }); } catch (Exception ex) { LogWriter.Log(ex, "Invoke error."); } #endregion }
/// <summary> /// Thread method that encodes the list of frames. /// </summary> private void DoWork() { int countList = _listBitmap.Count; var processing = new Processing(); this.Invoke((Action)delegate //Needed because it's a cross thread call. { //Control ctrlParent = panelTransparent; //Processing processing = new Processing(); panelTransparent.Controls.Add(processing); processing.Dock = DockStyle.Fill; processing.SetMaximumValue(countList); processing.SetStatus(1); }); if (Settings.Default.STencodingCustom) // if NGif encoding { #region Ngif encoding int numImage = 0; using (_encoder = new AnimatedGifEncoder()) { _encoder.Start(_outputpath); _encoder.SetQuality(Settings.Default.STquality); _encoder.SetRepeat(Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once try { foreach (var image in _listBitmap) { numImage++; this.BeginInvoke((Action)(() => processing.SetStatus(numImage))); _encoder.SetFrameRate(Convert.ToInt32(numMaxFps.Value)); _encoder.AddFrame(image); } } catch (Exception ex) { LogWriter.Log(ex, "Ngif encoding."); } } #endregion } else //if paint.NET encoding { #region paint.NET encoding //var imageArray = _listBitmap.ToArray(); var delay = 1000 / Convert.ToInt32(numMaxFps.Value); var repeat = (Settings.Default.STloop ? (Settings.Default.STrepeatForever ? 0 : Settings.Default.STrepeatCount) : -1); // 0 = Always, -1 once using (var stream = new MemoryStream()) { using (var encoderNet = new GifEncoder(stream, null, null, repeat)) { for (int i = 0; i < _listBitmap.Count; i++) { encoderNet.AddFrame((_listBitmap[i]).CopyImage(), 0, 0, TimeSpan.FromMilliseconds(delay)); this.Invoke((Action)(() => processing.SetStatus(i))); } } stream.Position = 0; using ( var fileStream = new FileStream(_outputpath, FileMode.Create, FileAccess.Write, FileShare.None, Constants.BufferSize, false)) { stream.WriteTo(fileStream); } } #endregion } #region Memory Clearing //TODO: Clean the list of delay. listFramesPrivate.Clear(); listFramesUndo.Clear(); listFramesUndoAll.Clear(); listFramesPrivate = null; listFramesUndo = null; listFramesUndoAll = null; _encoder = null; GC.Collect(); //call the garbage colector to empty the memory #endregion #region Finish try { this.Invoke((Action)delegate //must use invoke because it's a cross thread call { _caller.Text = Resources.Title_EncodingDone; _stage = (int)Stage.Stoped; panelTransparent.Controls.Clear(); //Clears the processing page. processing.Dispose(); _caller.Invalidate(); btnRecordPause.Text = Resources.btnRecordPause_Record; btnRecordPause.Image = Properties.Resources.Record; flowPanel.Enabled = true; //_caller.TopMost = false; _caller.TopMost = false; numMaxFps.Enabled = true; tbHeight.Enabled = true; tbWidth.Enabled = true; _caller.MaximizeBox = true; _caller.MinimizeBox = true; _actHook.KeyDown += KeyHookTarget; //Set again the keyboard hook method _actHook.Start(false, true); //start again the keyboard hook watcher }); } catch (Exception ex) { LogWriter.Log(ex, "Invoke error."); } #endregion }