/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels"> /// The pixel data (bottom line first). /// </param> /// <param name="dpi"> /// The image resolution in dots per inch. /// </param> /// <returns> /// The png image data. /// </returns> public static byte[] Encode(OxyColor[,] pixels, int dpi = 96) { int height = pixels.GetLength(0); int width = pixels.GetLength(1); var bytes = new byte[(width * height * 4) + height]; int k = 0; for (int i = height - 1; i >= 0; i--) { bytes[k++] = 0; // Filter for (int j = 0; j < width; j++) { bytes[k++] = pixels[i, j].R; bytes[k++] = pixels[i, j].G; bytes[k++] = pixels[i, j].B; bytes[k++] = pixels[i, j].A; } } var w = new MemoryWriter(); w.Write((byte)0x89); w.Write("PNG\r\n\x1a\n".ToCharArray()); WriteChunk(w, "IHDR", CreateHeaderData(width, height)); WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi)); WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes)); WriteChunk(w, "IEND", new byte[0]); return(w.ToArray()); }
/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels">The pixel data indexed as [x,y] (bottom line first).</param> /// <returns>The png image data.</returns> public byte[] Encode(OxyColor[,] pixels) { int width = pixels.GetLength(0); int height = pixels.GetLength(1); var bytes = new byte[(width * height * 4) + height]; int k = 0; for (int y = 0; y < height; y++) { bytes[k++] = 0; // Filter for (int x = 0; x < width; x++) { bytes[k++] = pixels[x, y].R; bytes[k++] = pixels[x, y].G; bytes[k++] = pixels[x, y].B; bytes[k++] = pixels[x, y].A; } } var w = new MemoryWriter(); w.Write((byte)0x89); w.Write("PNG\r\n\x1a\n".ToCharArray()); WriteChunk(w, "IHDR", CreateHeaderData(width, height)); WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(this.options.DpiX, this.options.DpiY)); WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes)); WriteChunk(w, "IEND", new byte[0]); return(w.ToArray()); }
/// <summary> /// Creates the uncompressed blocks. /// </summary> /// <param name="bytes"> /// The data. /// </param> /// <returns> /// The output data. /// </returns> private static byte[] CreateUncompressedBlocks(byte[] bytes) { // http://www.w3.org/TR/PNG-Compression.html const int MaxDeflate = 0xFFFF; var w = new MemoryWriter(); const uint CompressionMethod = 8; const uint Check = (31 - ((CompressionMethod << 8) % 31)) % 31; w.Write((byte)CompressionMethod); w.Write((byte)Check); for (int i = 0; i < bytes.Length; i += MaxDeflate) { var n = (ushort)Math.Min(bytes.Length - i, MaxDeflate); var last = (byte)(i + n < bytes.Length ? 0 : 1); w.Write(last); w.Write((byte)(n & 0xFF)); w.Write((byte)((n >> 8) & 0xFF)); var n2 = ~n; w.Write((byte)(n2 & 0xFF)); w.Write((byte)((n2 >> 8) & 0xFF)); w.Write(bytes, i, n); } WriteBigEndian(w, Adler32(bytes)); return(w.ToArray()); }
/// <summary> /// Creates the physical dimensions data. /// </summary> /// <param name="dpix"> /// The horizontal resolution. /// </param> /// <param name="dpiy"> /// The vertical resolution. /// </param> /// <returns> /// The data. /// </returns> private static byte[] CreatePhysicalDimensionsData(int dpix, int dpiy) { var ppux = (int)(dpix / 0.0254); var ppuy = (int)(dpiy / 0.0254); var w = new MemoryWriter(); WriteBigEndian(w, ppux); WriteBigEndian(w, ppuy); w.Write((byte)1); // Unit: metre return(w.ToArray()); }
/// <summary> /// Creates the header data. /// </summary> /// <param name="width"> /// The width. /// </param> /// <param name="height"> /// The height. /// </param> /// <returns> /// The header. /// </returns> private static byte[] CreateHeaderData(int width, int height) { // http://www.w3.org/TR/PNG-Chunks.html var w = new MemoryWriter(); WriteBigEndian(w, width); WriteBigEndian(w, height); w.Write((byte)8); // bit depth w.Write((byte)6); // color type RGBA w.Write((byte)0); // compression method w.Write((byte)0); // filter method w.Write((byte)0); // interlace method return(w.ToArray()); }
/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels"> /// The pixel data (bottom line first). /// </param> /// <param name="dpi"> /// The image resolution in dots per inch. /// </param> /// <returns> /// The png image data. /// </returns> public static byte[] Encode(OxyColor[,] pixels, int dpi = 96) { int height = pixels.GetLength(0); int width = pixels.GetLength(1); var bytes = new byte[(width * height * 4) + height]; int k = 0; for (int i = height - 1; i >= 0; i--) { bytes[k++] = 0; // Filter for (int j = 0; j < width; j++) { bytes[k++] = pixels[i, j].R; bytes[k++] = pixels[i, j].G; bytes[k++] = pixels[i, j].B; bytes[k++] = pixels[i, j].A; } } var w = new MemoryWriter(); w.Write((byte)0x89); w.Write("PNG\r\n\x1a\n".ToCharArray()); WriteChunk(w, "IHDR", CreateHeaderData(width, height)); WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi)); WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes)); WriteChunk(w, "IEND", new byte[0]); return w.ToArray(); }
/// <summary> /// Creates the uncompressed blocks. /// </summary> /// <param name="bytes"> /// The data. /// </param> /// <returns> /// The output data. /// </returns> private static byte[] CreateUncompressedBlocks(byte[] bytes) { // http://www.w3.org/TR/PNG-Compression.html const int MaxDeflate = 0xFFFF; var w = new MemoryWriter(); const uint CompressionMethod = 8; const uint Check = (31 - ((CompressionMethod << 8) % 31)) % 31; w.Write((byte)CompressionMethod); w.Write((byte)Check); for (int i = 0; i < bytes.Length; i += MaxDeflate) { var n = (ushort)Math.Min(bytes.Length - i, MaxDeflate); var last = (byte)(i + n < bytes.Length ? 0 : 1); w.Write(last); w.Write((byte)(n & 0xFF)); w.Write((byte)((n >> 8) & 0xFF)); var n2 = ~n; w.Write((byte)(n2 & 0xFF)); w.Write((byte)((n2 >> 8) & 0xFF)); w.Write(bytes, i, n); } WriteBigEndian(w, Adler32(bytes)); return w.ToArray(); }
/// <summary> /// Creates the physical dimensions data. /// </summary> /// <param name="dpix"> /// The horizontal resolution. /// </param> /// <param name="dpiy"> /// The vertical resolution. /// </param> /// <returns> /// The data. /// </returns> private static byte[] CreatePhysicalDimensionsData(int dpix, int dpiy) { var ppux = (int)(dpix / 0.0254); var ppuy = (int)(dpiy / 0.0254); var w = new MemoryWriter(); WriteBigEndian(w, ppux); WriteBigEndian(w, ppuy); w.Write((byte)1); // Unit: metre return w.ToArray(); }
/// <summary> /// Creates the header data. /// </summary> /// <param name="width"> /// The width. /// </param> /// <param name="height"> /// The height. /// </param> /// <returns> /// The header. /// </returns> private static byte[] CreateHeaderData(int width, int height) { // http://www.w3.org/TR/PNG-Chunks.html var w = new MemoryWriter(); WriteBigEndian(w, width); WriteBigEndian(w, height); w.Write((byte)8); // bit depth w.Write((byte)6); // color type RGBA w.Write((byte)0); // compression method w.Write((byte)0); // filter method w.Write((byte)0); // interlace method return w.ToArray(); }
/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels">The pixel data indexed as [x,y] (bottom line first).</param> /// <returns>The png image data.</returns> public byte[] Encode(OxyColor[,] pixels) { int width = pixels.GetLength(0); int height = pixels.GetLength(1); var bytes = new byte[(width * height * 4) + height]; int k = 0; for (int y = 0; y < height; y++) { bytes[k++] = 0; // Filter for (int x = 0; x < width; x++) { bytes[k++] = pixels[x, y].R; bytes[k++] = pixels[x, y].G; bytes[k++] = pixels[x, y].B; bytes[k++] = pixels[x, y].A; } } var w = new MemoryWriter(); w.Write((byte)0x89); w.Write("PNG\r\n\x1a\n".ToCharArray()); WriteChunk(w, "IHDR", CreateHeaderData(width, height)); WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(this.options.DpiX, this.options.DpiY)); WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes)); WriteChunk(w, "IEND", new byte[0]); return w.ToArray(); }