/// <summary> /// Creates a PNG image from the specified pixels. /// </summary> /// <param name="pixels">The pixels (bottom line first).</param> /// <returns>An OxyImage.</returns> public static OxyImage PngFromArgb(OxyColor[,] pixels) { return(new OxyImage(PngEncoder.Encode(pixels))); }
private OxyImage GetGradientImage(OxyColor color1, OxyColor color2) { int n = 256; var imageData = new OxyColor[1, n]; for (int i = 0; i < n; i++) { imageData[0, i] = OxyColor.Interpolate(color1, color2, i / (n - 1.0)); } var encoder = new PngEncoder(new PngEncoderOptions()); return new OxyImage(encoder.Encode(imageData)); }
/// <summary> /// Decodes an image from the specified byte array. /// </summary> /// <param name="bytes">The image data.</param> /// <returns>The 32-bit pixel data, indexed as [x,y].</returns> public OxyColor[,] Decode(byte[] bytes) { // http://www.w3.org/TR/PNG/ // http://en.wikipedia.org/wiki/Portable_Network_Graphics var s = new MemoryStream(bytes); var inputReader = new BinaryReader(s); var signature = inputReader.ReadBytes(8); if (signature[0] != 0x89 || signature[1] != 0x50 || signature[2] != 0x4E || signature[3] != 0x47 || signature[4] != 0x0D || signature[5] != 0x0A || signature[6] != 0x1A || signature[7] != 0x0A) { throw new FormatException("Invalid signature."); } var headerLength = inputReader.ReadBigEndianUInt32(); if (headerLength != 13) { throw new FormatException("Header not supported."); } var headerType = inputReader.ReadString(4); if (headerType != "IHDR") { throw new FormatException("Invalid header."); } var width = (int)inputReader.ReadBigEndianUInt32(); var height = (int)inputReader.ReadBigEndianUInt32(); var bitDepth = inputReader.ReadByte(); var colorType = (ColorType)inputReader.ReadByte(); var compressionMethod = (CompressionMethod)inputReader.ReadByte(); var filterMethod = (FilterMethod)inputReader.ReadByte(); var interlaceMethod = (InterlaceMethod)inputReader.ReadByte(); inputReader.ReadBigEndianUInt32(); // headerCRC if (bitDepth != 8) { throw new NotImplementedException(); } if (colorType != ColorType.TrueColorWithAlpha) { throw new NotImplementedException(); } if (compressionMethod != CompressionMethod.Deflate) { throw new NotImplementedException(); } if (filterMethod != FilterMethod.None) { throw new NotImplementedException(); } if (interlaceMethod != InterlaceMethod.None) { throw new NotImplementedException(); } var ms = new MemoryStream(); while (true) { var length = (int)inputReader.ReadBigEndianUInt32(); var type = inputReader.ReadString(4); if (type == "IEND") { break; } switch (type) { case "PLTE": throw new NotImplementedException(); case "IDAT": { inputReader.ReadByte(); // method inputReader.ReadByte(); // check var chunkBytes = inputReader.ReadBytes(length - 6); var expectedCheckSum = inputReader.ReadBigEndianUInt32(); var deflatedBytes = Deflate(chunkBytes); var actualCheckSum = PngEncoder.Adler32(deflatedBytes); if (actualCheckSum != expectedCheckSum) { throw new FormatException("Invalid checksum."); } ms.Write(deflatedBytes, 0, deflatedBytes.Length); break; } default: { inputReader.ReadBytes(length); break; } } inputReader.ReadBigEndianUInt32(); // crc } var pixels = new OxyColor[width, height]; ms.Position = 0; for (int y = height - 1; y >= 0; y--) { ms.ReadByte(); for (int x = 0; x < width; x++) { var red = (byte)ms.ReadByte(); var green = (byte)ms.ReadByte(); var blue = (byte)ms.ReadByte(); var alpha = (byte)ms.ReadByte(); pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue); } } /* * var bitReader = new ByteBitReader(ms); * for (int y = 0; y < height; y++) * { * var filterType = bitReader.readByte(); * for (int x = 0; x < width; x++) * { * var red = (byte)bitReader.ReadBits(bitDepth); * var green = (byte)bitReader.ReadBits(bitDepth); * var blue = (byte)bitReader.ReadBits(bitDepth); * var alpha = (byte)bitReader.ReadBits(bitDepth); * * pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue); * } * }*/ if (ms.Position != ms.Length) { throw new InvalidOperationException(); } return(pixels); }