Encodes multiple images as an animated gif to a stream.
ALWAYS wire this up in a "using" block
Disposing the encoder will complete the file.
Uses default .net GIF encoding and adds animation headers.
Наследование: IDisposable
Пример #1
0
        /// <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
        }
Пример #2
0
        /// <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
        }
Пример #3
0
        /// <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
        }