/// <summary> /// Creates an Animated PNG from a Image. /// </summary> /// <returns>The file.</returns> /// <param name="image">Image.</param> public static APNG FromImage(Image image) { APNG apng = new APNG(); apng.Load(APNG.ImageToStream(image)); return(apng); }
/// <summary> /// Creates an Animated PNG from a file. /// </summary> /// <returns>The file.</returns> /// <param name="filename">Filename.</param> public static APNG FromFile(string filename) { APNG apng = new APNG(); apng.Load(filename); return(apng); }
/// <summary> /// Creates an Animated PNG from a stream. /// </summary> /// <returns>The file.</returns> /// <param name="stream">The stream.</param> public static APNG FromStream(MemoryStream stream) { APNG apng = new APNG(); apng.Load(stream); return(apng); }
/// <summary> /// Adds an image as the next frame. /// </summary> /// <param name="image">Png frame.</param> public void AddFrame(Image image) { //TODO: Handle different sizes //Temporarily reject improper sizes. if (IHDRChunk != null && (image.Width > IHDRChunk.Width || image.Height > IHDRChunk.Height)) { throw new InvalidDataException("Frame must be less than or equal to the size of the other frames."); } APNG apng = APNG.FromImage(image); if (IHDRChunk == null) { IHDRChunk = apng.IHDRChunk; } //Create acTL Chunk. if (acTLChunk == null) { acTLChunk = new acTLChunk(); acTLChunk.PlayCount = 0; } uint sequenceNumber = (frames.Count == 0) ? 0 : (uint)(frames[frames.Count - 1].fcTLChunk.SequenceNumber + frames[frames.Count - 1].IDATChunks.Count); //Create fcTL Chunk fcTLChunk fctl = new fcTLChunk { SequenceNumber = sequenceNumber, Width = (uint)image.Width, Height = (uint)image.Height, XOffset = 0, YOffset = 0, DelayNumerator = 100, DelayDenominator = 1000, DisposeOp = DisposeOps.APNGDisposeOpNone, BlendOp = BlendOps.APNGBlendOpSource }; //Set the default image if needed. if (defaultImage.IDATChunks.Count == 0) { defaultImage = apng.DefaultImage; defaultImage.fcTLChunk = fctl; DefaultImageIsAnimated = true; } //Add all the frames from the png. if (apng.IsSimplePNG) { Frame frame = apng.DefaultImage; frame.fcTLChunk = fctl; foreach (OtherChunk chunk in frame.OtherChunks) { if (!defaultImage.OtherChunks.Contains(chunk)) { defaultImage.OtherChunks.Add(chunk); } } frame.OtherChunks.Clear(); frames.Add(frame); } else { for (int i = 0; i < apng.FrameCount; ++i) { Frame frame = apng.Frames[i]; frame.fcTLChunk.SequenceNumber = sequenceNumber; foreach (OtherChunk chunk in frame.OtherChunks) { if (!defaultImage.OtherChunks.Contains(chunk)) { defaultImage.OtherChunks.Add(chunk); } } frame.OtherChunks.Clear(); frames.Add(frame); } } List <OtherChunk> otherChunks = defaultImage.OtherChunks; // Now we should apply every chunk in otherChunks to every frame. if (defaultImage != frames[0]) { frames.ForEach(f => otherChunks.ForEach(f.AddOtherChunk)); } else { for (int i = 1; i < frames.Count; ++i) { otherChunks.ForEach(frames[i].AddOtherChunk); } } acTLChunk.FrameCount = (uint)frames.Count; }