public Fctl(Ihdr ihdr, UInt32 frame, UInt32 x, UInt32 y, UInt32 width, UInt32 height, Rational delay, ApngDisposeOperation disposeOp, ApngBlendOperation blendOp) : base(ChunkType.fcTL) { #region sanity if(width == 0) throw new ArgumentOutOfRangeException("width", "width must be > 0"); if(height == 0) throw new ArgumentOutOfRangeException("height", "height must be > 0"); if(x + width > ihdr.Width) throw new ArgumentException("x + width(" + (x + (UInt64)width) + ") must be smaller than canvas width: " + ihdr.Width); if(y + height > ihdr.Height) throw new ArgumentException("y + height(" + (y + (UInt64)height) + ") must be smaller than canvas height: " + ihdr.Height); #endregion _frame = frame; _x = x; _y = y; _width = width; _height = height; _delay = delay; _disposeOp = disposeOp; _blendOp = blendOp; _memStream.Write(NoHelper.GetBytes(_frame), 0, 4); _memStream.Write(NoHelper.GetBytes(_width), 0, 4); _memStream.Write(NoHelper.GetBytes(_height), 0, 4); _memStream.Write(NoHelper.GetBytes(_x), 0, 4); _memStream.Write(NoHelper.GetBytes(_y), 0, 4); _memStream.Write(NoHelper.GetBytes(delay.Numerator), 0, 2); _memStream.Write(NoHelper.GetBytes(delay.Denominator), 0, 2); _memStream.WriteByte((Byte)disposeOp); _memStream.WriteByte((Byte)blendOp); }
//read http://stackoverflow.com/questions/6216094/implementing-the-apng-render-function public Tuple<Fctl, Fdat> EncodeFrame(Ihdr ihdr, InternalImage img, uint sequenceNumber, InternalImage lastImage, Rational delay) { //Rectangle bb = CalculateDifferenceBoundingBox(img, lastImage); //float approxns = ApproximateCompressionSize(img, lastImage, bb, ApngDisposeOperation.None, ApngBlendOperation.Source); //float approxns = ApproximateCompressionSize(img, lastImage, bb, ApngDisposeOperation., ApngBlendOperation.Source); return new Tuple<Fctl, Fdat>(new Fctl(ihdr, sequenceNumber, 0, 0, img.Ihdr.Width, img.Ihdr.Height, delay, ApngDisposeOperation.None, ApngBlendOperation.Source), new Fdat(sequenceNumber+1, Encode(img, lastImage), true)); }
private static void TestEncoder(UInt32 imageDimension, IEncoder enc) { var i = new Bitmap((int)imageDimension, (int)imageDimension, PixelFormat.Format24bppRgb); var g = Graphics.FromImage(i); g.FillRectangle(new SolidBrush(Color.Transparent), 0, 0, i.Width, i.Height); g.DrawEllipse(new Pen(Color.IndianRed), 1, 1, i.Width / 2, i.Height / 2); g.DrawRectangle(new Pen(Color.GreenYellow, 4), i.Width / 2, i.Width / 2, i.Width / 2 - 4, i.Width / 2 - 4); var ihdr = new Ihdr(imageDimension, imageDimension, BitDepth._8, ColorType.Rgb); var apng = new APNG(ihdr); apng.RegisterDecoder(new SimpleDecoder()); apng.Encoder = enc; apng.AddDefaultImageFromObject(i); var frames = new Frame[i.Height / 2]; for(int j = 0; j < i.Height / 2; j++) { var bmp = new Bitmap((int)imageDimension, (int)imageDimension, PixelFormat.Format24bppRgb); var gr = Graphics.FromImage(bmp); gr.Clear(Color.Blue); gr.DrawEllipse(new Pen(Color.Lime), bmp.Width / 4, j, bmp.Width / 2, bmp.Height / 2); frames[j] = new Frame() { Delay = new Rational(10, 100), FrameObject = bmp }; } apng.SetFrames(frames); String fileName = String.Format("{0}_{1}x{2}_{3}.png", enc.GetType().Name, imageDimension, imageDimension, 0); if(File.Exists(fileName)) File.Delete(fileName); apng.ToFile(fileName); ihdr = new Ihdr(imageDimension, imageDimension, BitDepth._8, ColorType.Rgb); apng = new APNG(ihdr); apng.RegisterDecoder(new SimpleDecoder()); apng.Encoder = enc; String nowString = DateTime.UtcNow.ToString(@"yyyy\-MM\-dd HH:mm"); g.Clear(Color.Blue); g.DrawString(nowString, new Font("Consolas", 7), new SolidBrush(Color.Lime), 5, i.Height / 2f); apng.AddDefaultImageFromObject(i); frames = new Frame[i.Height / 2-10]; for(int j = 10; j < i.Height / 2; j++) { var bmp = new Bitmap((int)imageDimension, (int)imageDimension, PixelFormat.Format24bppRgb); var gr = Graphics.FromImage(bmp); gr.Clear(Color.Blue); gr.DrawString(nowString, new Font("Consolas", 7), new SolidBrush(Color.Lime), 5, j); frames[j-10] = new Frame() { Delay = new Rational(10, 100), FrameObject = bmp }; } apng.SetFrames(frames); fileName = String.Format("{0}_{1}x{2}_{3}.png", enc.GetType().Name, imageDimension, imageDimension, 1); if(File.Exists(fileName)) File.Delete(fileName); apng.ToFile(fileName); }
public InternalImage(Ihdr ihdr, byte[] rgbData, byte[] rgbPaletteData) { Ihdr = ihdr; RgbData = rgbData; RgbPaletteData = rgbPaletteData; }
public InternalImage(Ihdr ihdr) { Ihdr = ihdr; }
public Tuple<Fctl, Idat> EncodeImage(Ihdr ihdr, InternalImage img, uint sequenceNumber) { return new Tuple<Fctl, Idat>(new Fctl(ihdr, sequenceNumber, 0, 0, img.Ihdr.Width, img.Ihdr.Height, new Rational(0, 0), ApngDisposeOperation.None, ApngBlendOperation.Source), new Idat(Encode(img, null), true)); }
public InternalImage Decode(Object obj, Ihdr ihdr, byte[] usePalette = null) { if(obj == null) throw new ArgumentNullException("obj"); var bitmap = obj as Bitmap; if(bitmap == null) throw new NotSupportedException(GetType().Name + " is unable to decode object type " + obj.GetType().Name); #region sanity if(bitmap.Width != ihdr.Width) throw new ArgumentException("bitmap.Width should be " + ihdr.Width + " is " + bitmap.Width, "obj"); if(bitmap.Height != ihdr.Height) throw new ArgumentException("bitmap.Height should be " + ihdr.Height + " is " + bitmap.Height, "obj"); #endregion var intImage = new InternalImage(ihdr); switch (ihdr.ColorType) { case ColorType.Palette: if(usePalette == null) intImage.RgbPaletteData = CreatePalette(bitmap); intImage.RgbData = CreateImageIndices(bitmap, ihdr, usePalette ?? intImage.RgbPaletteData); break; case ColorType.Grayscale: throw new NotImplementedException(); break; case ColorType.Rgb: intImage.RgbData =CreateImageRgb(bitmap, ihdr); break; case ColorType.GrayscaleWithAlpha: throw new NotImplementedException(); break; case ColorType.Rgba: throw new NotImplementedException(); break; default: throw new ArgumentOutOfRangeException(); } #region unable to process //switch(bitmap.PixelFormat) // { // case PixelFormat.Indexed: // throw new NotImplementedException(); // break; // case PixelFormat.Format1bppIndexed: // throw new NotImplementedException(); // break; // case PixelFormat.Format4bppIndexed: // throw new NotImplementedException(); // break; // case PixelFormat.Format8bppIndexed: // throw new NotImplementedException(); // break; // case PixelFormat.Format16bppGrayScale: // throw new NotImplementedException(); // break; // case PixelFormat.Format16bppRgb555: // throw new NotImplementedException(); // break; // case PixelFormat.Format16bppRgb565: // throw new NotImplementedException(); // break; // case PixelFormat.Format16bppArgb1555: // throw new NotImplementedException(); // break; // case PixelFormat.Format24bppRgb: // throw new NotImplementedException(); // break; // case PixelFormat.Format32bppRgb: // if(ihdr.ColorType == ColorType.Rgb && ihdr.BitDepth == BitDepth._8) // ; // else // throw new NotImplementedException(); // break; // case PixelFormat.Format32bppArgb: // throw new NotImplementedException(); // break; // //case PixelFormat.Format32bppPArgb: // //case PixelFormat.Alpha: // //case PixelFormat.PAlpha: // //case PixelFormat.Extended: // //case PixelFormat.Canonical: // //case PixelFormat.Undefined: // //case PixelFormat.Format48bppRgb: // //case PixelFormat.Format64bppArgb: // //case PixelFormat.Format64bppPArgb: // //case PixelFormat.Max: // //case PixelFormat.Gdi: // default: // throw new UnsupportedPixelTypeException("Image pixel format unsupported: " + bitmap.PixelFormat); // } #endregion return intImage; }
private byte[] CreateImageRgb(Bitmap bitmap, Ihdr ihdr) { BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); //will actually be bgr try { var row = new byte[bitmap.Width * 3]; var destBytes = new byte[bitmap.Width * 3 * bitmap.Height]; for(int y = 0; y < bmpData.Height; ++y) { Marshal.Copy(bmpData.Scan0 + (y * bmpData.Stride), row, 0, bmpData.Width * 3); for(int i = 0; i < bitmap.Width * 3; i+=3) { destBytes[y * ((bmpData.Width * 3)) + i] = row[i + 2]; destBytes[y * ((bmpData.Width * 3)) + i + 1] = row[i + 1]; destBytes[y * ((bmpData.Width * 3)) + i + 2] = row[i]; } } //var destBytes = new byte[bitmap.Width * 3 * bitmap.Height + 1]; //destBytes[0] = 0x00; //for(int y = 0; y < bmpData.Height; ++y) // Marshal.Copy(bmpData.Scan0 + y * bmpData.Stride, destBytes, 1 + (y * bitmap.Width * 3), bmpData.Width * 3); return destBytes; } finally { bitmap.UnlockBits(bmpData); } }
private byte[] CreateImageIndices(Bitmap bitmap, Ihdr ihdr, byte[] palette) { throw new NotImplementedException(); }
public APNG(Ihdr ihdr, UInt32 loops = 0) { Loops = loops; _crc32 = new Crc32(); Ihdr = ihdr; }
public Tuple<Fctl, Fdat> EncodeFrame(Ihdr ihdr, InternalImage img, uint sequenceNumber, InternalImage lastImage, Rational delay) { return new Tuple<Fctl, Fdat>(new Fctl(ihdr, sequenceNumber, 0, 0, img.Ihdr.Width, img.Ihdr.Height, delay, ApngDisposeOperation.None, ApngBlendOperation.Source), new Fdat(sequenceNumber+1, Encode(img, lastImage), true)); }