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(); }
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(); }
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(); }
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); }
public static StciIndexed ConvertGifToStciIndexed(GifBitmapCoder aCoder, bool aIsTransparent, bool aIsTrim) { return(ConvertGifToStciIndexed(aCoder, aIsTransparent, aIsTrim)); }
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); }
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); }