示例#1
0
        private static void GifCoderTest()
        {
            var _gifFileName = "F_LAW.gif";

            var _input = new FileStream(_gifFileName, FileMode.Open);

            var _gifCoder = new GifBitmapCoder();

            _gifCoder.Load(_input);
            _input.Close();

            for (int i = 0; i < _gifCoder.Frames.Count; i++)
            {
                var _output  = String.Format(@"result\{0}{1:d3}.gif", Path.GetFileNameWithoutExtension(_gifFileName), i);
                var _encoder = new GifBitmapEncoder();
                _encoder.Frames.Add(_gifCoder.Frames[i].Frame);

                using (var _fs = new FileStream(_output, FileMode.Create))
                {
                    _encoder.Save(_fs);
                }
            }

            var _output1 = new FileStream("output.gif", FileMode.Create);

            _gifCoder.Save(_output1);
            _output1.Close();
        }
示例#2
0
        static void Main(string[] args)
        {
            //var _gifFileName = "truck_crush.gif";
            var _gifFileName = "football.gif";

            var _gifCoder = new GifBitmapCoder();
            var _input    = new FileStream(_gifFileName, FileMode.Open);

            _gifCoder.Load(_input);

            _input.Close();

            for (int i = 0; i < _gifCoder.Frames.Count; i++)
            {
                _gifCoder.Frames[i].Delay = 1 + i % 31;
                //_gifCoder.Frames[i].Delay = 11;

                var _encoder = new BmpBitmapEncoder();
                _encoder.Frames.Add(_gifCoder.Frames[i].Frame);

                string _file = String.Format(@"result\output{0}.bmp", i);
                var    _fs   = new FileStream(_file, FileMode.Create);
                _encoder.Save(_fs);
                _fs.Close();
            }

            var _outputFileName = "football_slow_mo.gif";
            //var _outputFileName = "truck_crush.gif";
            var _output = new FileStream(_outputFileName, FileMode.Create);

            _gifCoder.Save(_output);

            _output.Close();
        }
示例#3
0
        private static void DisposalMethodTest()
        {
            // var _fileName = "SpartanFla.gif";
            var _fileName = "output.gif";

            var _input = new FileStream(_fileName, FileMode.Open);

            var _gifCoder = new GifBitmapCoder();

            _gifCoder.Load(_input);
            _input.Close();

            foreach (var _frame in _gifCoder.Frames)
            {
                // _frame.DisposalMethod = GifFrameDisposalMethod.RestoreToPrevious;
                _frame.DisposalMethod = GifFrameDisposalMethod.NotDispose;
            }

            var _output = new FileStream("output.gif", FileMode.Create);

            _gifCoder.Save(_output);
            _output.Close();
        }
示例#4
0
        private void Convert(string aFileName)
        {
            if (FOffsetX == null && !String.IsNullOrEmpty(this.OffsetFileName))
            {
                string _data = null;
                using (var _offsetFile = File.OpenText(this.FOffsetFileName))
                {
                    _data = _offsetFile.ReadToEnd();
                }

                string[] _offsets = _data.Split(new char[] { ' ', '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (_offsets.Length % 2 != 0)
                {
                    throw new FileFormatException("Odd numbers in offset file.");
                }

                this.FOffsetX = new short[_offsets.Length / 2];
                this.FOffsetY = new short[_offsets.Length / 2];
                for (int i = 0; i < _offsets.Length; i++)
                {
                    short _offset = 0;
                    if (Int16.TryParse(_offsets[i], out _offset))
                    {
                        if (i % 2 == 0)
                        {
                            this.FOffsetX[i / 2] = _offset;
                        }
                        else
                        {
                            this.FOffsetY[i / 2] = _offset;
                        }
                    }
                    else
                    {
                        throw new FileFormatException("Can't parse number in offset file.");
                    }
                }
            }

            var _input = new FileStream(aFileName, FileMode.Open);

            var _gifDecoder = new GifBitmapCoder();

            _gifDecoder.Load(_input);
            _input.Close();

            foreach (var _frame in _gifDecoder.Frames)
            {
                if (!_frame.UseGlobalPalette)
                {
                    this.ExceptionString =
                        "Внимание! В GIF файле для некоторых кадров используются локальные палитры. Изображение будет искажено.";
                    break;
                }
            }

            var _stci = Converter.ConvertGifToStciIndexed(
                _gifDecoder, this.IsTransparentBackground, this.IsTrimBackground, this.ForeshotingAmount);

            if (this.FOffsetX != null)
            {
                if (this.FOffsetX.Length > 1 && _stci.Images.Length != this.FOffsetX.Length)
                {
                    throw new ArgumentOutOfRangeException("Number frames in STCI is not equal to number of records in offset file");
                }

                for (int i = 0; i < _stci.Images.Length; i++)
                {
                    if (this.FOffsetX.Length == 1)
                    {
                        _stci.Images[i].Header.OffsetX = this.FOffsetX[0];
                        _stci.Images[i].Header.OffsetY = this.FOffsetY[0];
                    }
                    else
                    {
                        _stci.Images[i].Header.OffsetX = this.FOffsetX[i];
                        _stci.Images[i].Header.OffsetY = this.FOffsetY[i];
                    }
                }
            }

            using (var _output = new FileStream(Path.ChangeExtension(aFileName, ".sti"), FileMode.Create))
                _stci.Save(_output);
        }
示例#5
0
 public static StciIndexed ConvertGifToStciIndexed(GifBitmapCoder aCoder, bool aIsTransparent, bool aIsTrim)
 {
     return(ConvertGifToStciIndexed(aCoder, aIsTransparent, aIsTrim));
 }
示例#6
0
        public static GifBitmapCoder ConvertStciIndexedToGif(
            StciIndexed aStci, UInt16 aDelay, bool aUseTransparent, int aForeshotingNumber)
        {
            var _stciPalette = aStci.Palette;
            var _colors      = new List <Color>(StciIndexed.NUMBER_OF_COLORS);

            for (int i = 0; i < StciIndexed.NUMBER_OF_COLORS; i++)
            {
                _colors.Add(Color.FromRgb(_stciPalette[i * 3], _stciPalette[i * 3 + 1], _stciPalette[i * 3 + 2]));
            }
            var _palette = new BitmapPalette(_colors);

            var _gifCoder = new GifBitmapCoder(_palette);

            _gifCoder.Extensions.Add(new GifCommentExtension("Egorov A. V. for ja2.su"));

            Int16 _minOffsetX = Int16.MaxValue;
            Int16 _minOffsetY = Int16.MaxValue;

            int foreshotingCount = 0;

            foreach (var _subImage in aStci.Images)
            {
                if (_subImage.AuxData != null && _subImage.AuxData.NumberOfFrames > 0)
                {
                    foreshotingCount++;
                }

                if (aForeshotingNumber > 0 && aForeshotingNumber != foreshotingCount)
                {
                    continue;
                }

                var _header = _subImage.Header;

                _minOffsetX = Math.Min(_minOffsetX, _header.OffsetX);
                _minOffsetY = Math.Min(_minOffsetY, _header.OffsetY);
            }

            if (_minOffsetX < 0 || _minOffsetY < 0)
            {
                var _shiftData = new List <byte>(4);
                _shiftData.AddRange(BitConverter.GetBytes(_minOffsetX));
                _shiftData.AddRange(BitConverter.GetBytes(_minOffsetY));
                var _shiftExtension = new GifApplicationExtension(ApplicationId, _shiftData.ToArray());
                _gifCoder.Extensions.Add(_shiftExtension);
            }

            foreshotingCount = 0;

            foreach (var _subImage in aStci.Images)
            {
                if (_subImage.AuxData != null && _subImage.AuxData.NumberOfFrames > 0)
                {
                    foreshotingCount++;
                }

                if (aForeshotingNumber > 0 && aForeshotingNumber != foreshotingCount)
                {
                    continue;
                }

                var _header = _subImage.Header;

                var _imageSource = BitmapSource.Create(
                    _header.Width,
                    _header.Height,
                    96, 96,
                    PixelFormats.Indexed8,
                    _palette,
                    _subImage.ImageData,
                    _header.Width);

                var _frame   = BitmapFrame.Create(_imageSource);
                var _offsetX = _header.OffsetX;
                var _offsetY = _header.OffsetY;
                if (_minOffsetX < 0 || _minOffsetY < 0)
                {
                    // GIF format suports only positive offsets
                    _offsetX = (short)(_offsetX - _minOffsetX);
                    _offsetY = (short)(_offsetY - _minOffsetY);
                }
                var _bf = new GifBitmapFrame(_frame, (ushort)_offsetX, (ushort)_offsetY);

                if (_subImage.AuxData != null)
                {
                    var _auxData = new byte[AuxObjectData.SIZE];
                    _subImage.AuxData.Save(new MemoryStream(_auxData));
                    _bf.Extensions.Add(new GifApplicationExtension(ApplicationId, _auxData));
                }

                _bf.DisposalMethod   = GifFrameDisposalMethod.RestoreToBackgroundColor;
                _bf.UseGlobalPalette = true;
                _bf.UseTransparency  = aUseTransparent;
                _bf.Delay            = aDelay;
                if (aUseTransparent)
                {
                    _bf.TransparentColorIndex = (byte)aStci.Header.TransparentColorIndex;
                }
                _gifCoder.AddFrame(_bf);
            }

            return(_gifCoder);
        }
示例#7
0
        public static StciIndexed ConvertGifToStciIndexed(
            GifBitmapCoder aCoder, bool aIsTransparent, bool aIsTrim, int aForeshotingAmount)
        {
            List <GifBitmapFrame> _bitmaps = aCoder.Frames;

            if (_bitmaps.Count == 0)
            {
                return(null);
            }

            var _subHeader = new StciIndexedHeader((ushort)_bitmaps.Count);
            var _palette   = new byte[StciIndexed.NUMBER_OF_COLORS * 3];
            //if (StciIndexed.NUMBER_OF_COLORS != _bitmaps[0].Frame.Palette.Colors.Count)
            //{
            //	throw new Exception(String.Format(
            //		"GIF file palette contains {0} colors. The {1} colors required.",
            //		_bitmaps[0].Frame.Palette.Colors.Count, StciIndexed.NUMBER_OF_COLORS));
            //}

            var _colorsCount = Math.Min(StciIndexed.NUMBER_OF_COLORS, _bitmaps[0].Frame.Palette.Colors.Count);

            for (int i = 0; i < _colorsCount; i++)
            {
                var _color = _bitmaps[0].Frame.Palette.Colors[i];
                _palette[i * 3]     = _color.R;
                _palette[i * 3 + 1] = _color.G;
                _palette[i * 3 + 2] = _color.B;
            }
            var _appDataSize = 0;

            if (_bitmaps[0].Extensions.FirstOrDefault(
                    x => x.ExtensionType == ExtensionType.ApplicationExtension &&
                    ((GifApplicationExtension)x).ApplicationId == ApplicationId) != null)
            {
                _appDataSize = _bitmaps.Count * 16;
            }

            var _header = new StciHeader(0, _bitmaps[0].TransparentColorIndex, (uint)_appDataSize, _subHeader);

            if (aIsTransparent)
            {
                _header.Flags |= StciFlags.STCI_TRANSPARENT;
            }

            var _subImages = new StciSubImage[_bitmaps.Count];

            var _shiftEx = aCoder.Extensions.FirstOrDefault(x => x.ExtensionType == ExtensionType.ApplicationExtension &&
                                                            ((GifApplicationExtension)x).ApplicationId == ApplicationId);

            int _shiftX = 0;
            int _shiftY = 0;

            if (_shiftEx != null)
            {
                _shiftX = BitConverter.ToInt16(_shiftEx.Data, 0);
                _shiftY = BitConverter.ToInt16(_shiftEx.Data, 2);
            }

            int _numberOfFrames = 0;

            if (aForeshotingAmount > 0)
            {
                _numberOfFrames = _bitmaps.Count / aForeshotingAmount;
            }

            // process disposal method
            BitmapFrame _prevFrame = null;

            for (int i = 0; i < _bitmaps.Count; i++)
            {
                if (_bitmaps[i].DisposalMethod == GifFrameDisposalMethod.NotDispose)
                {
                    var _bf = _bitmaps[i].Frame;
                    if (_prevFrame != null)
                    {
                        var    _wb     = new WriteableBitmap(_prevFrame);
                        byte[] _buffer = new byte[_bf.PixelWidth * _bf.PixelHeight];
                        _bf.CopyPixels(_buffer, _bf.PixelWidth, 0);
                        var _rect = new Int32Rect(_bitmaps[i].OffsetX, _bitmaps[i].OffsetY, _bf.PixelWidth, _bf.PixelHeight);

                        if (_prevFrame.PixelWidth < _rect.X + _rect.Width || _prevFrame.PixelHeight < _rect.Y + _rect.Height)
                        {
                            throw new Exception("Incorrect gif file.");
                        }

                        _wb.WritePixels(_rect, _buffer, _bf.PixelWidth, 0);
                        _bitmaps[i].Frame = BitmapFrame.Create(_wb);

                        _bitmaps[i].OffsetX = _bitmaps[i - 1].OffsetX;
                        _bitmaps[i].OffsetY = _bitmaps[i - 1].OffsetY;
                    }

                    _prevFrame = _bitmaps[i].Frame;
                }
            }

            // process trim
            if (aIsTrim)
            {
                for (int i = 0; i < _bitmaps.Count; i++)
                {
                    _bitmaps[i].Trim(aCoder.BackgroundColorIndex);
                }
            }

            // create subimages
            for (int i = 0; i < _bitmaps.Count; i++)
            {
                var _bf = _bitmaps[i].Frame;

                var _subImageHeader = new StciSubImageHeader();

                _subImageHeader.OffsetX = (short)(_bitmaps[i].OffsetX + _shiftX);
                _subImageHeader.OffsetY = (short)(_bitmaps[i].OffsetY + _shiftY);
                _subImageHeader.Width   = (ushort)_bf.PixelWidth;
                _subImageHeader.Height  = (ushort)_bf.PixelHeight;

                var _subImage = new StciSubImage(_subImageHeader);
                _subImage.ImageData = new byte[_subImage.Header.Width * _subImage.Header.Height];
                _bf.CopyPixels(_subImage.ImageData, _subImage.Header.Width, 0);

                if (aForeshotingAmount > 0)
                {
                    _subImage.AuxData = new AuxObjectData();
                    if (i % _numberOfFrames == 0)
                    {
                        _subImage.AuxData.Flags          = AuxObjectFlags.AUX_ANIMATED_TILE;
                        _subImage.AuxData.NumberOfFrames = (byte)_numberOfFrames;
                    }
                }
                else
                {
                    var _appDataExt = _bitmaps[i].Extensions.FirstOrDefault(x =>
                                                                            x.ExtensionType == ExtensionType.ApplicationExtension &&
                                                                            ((GifApplicationExtension)x).ApplicationId == ApplicationId);
                    if (_appDataExt != null)
                    {
                        _subImage.AuxData = new AuxObjectData();
                        _subImage.AuxData.Load(new MemoryStream(_appDataExt.Data));
                    }
                }

                _subImages[i] = _subImage;
            }

            var _stci = new StciIndexed(_header, _palette, _subImages);

            return(_stci);
        }