예제 #1
0
 /// <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));
        }
예제 #3
0
        /// <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);
        }