/// <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());
        }
예제 #2
0
        /// <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());
        }
예제 #6
0
        /// <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();
        }
예제 #7
0
        /// <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();
        }
예제 #8
0
 /// <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();
 }
예제 #9
0
 /// <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();
 }
예제 #10
0
        /// <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();
        }