示例#1
0
        // --------------------------------------------------------------
        #region PUBLIC FUNCTIONS
        // --------------------------------------------------------------

        /// <summary>
        /// Load the frame image
        /// </summary>
        /// <param name="_ImageData">Byte array to read</param>
        /// <param name="_ImageDataOffset">Data offset</param>
        /// <param name="m_Colours">Colors table to use</param>
        public void LoadFrameImage(byte[] _ImageData, long _ImageDataOffset, List <ColourEntry> m_Colours)
        {
            // create the VD image data array (in case we want to save the image in VD later)
            m_VDImageData = new string[m_width, m_height];

            // create the basic image
            m_image = new DirectBitmap(m_width, m_height);

            // get the current byte index
            int currByte = (int)((long)DataOffset - _ImageDataOffset);

            // starting x and y coordinates for drawing pixels
            int curx = 0;
            int cury = 0;

            // are we still within the image boundries?
            while (cury < m_height)
            {
                // get the next byte
                byte curr = _ImageData[currByte++];

                // are we positioned before the header?
                if (curr < (byte)128)
                {
                    // move to the correct starting point
                    for ( ; curr > (byte)0; curr--)
                    {
                        NextCoordinate(ref curx, ref cury, m_width, m_height);
                    }
                }
                else // correct position
                {
                    // get the next byte
                    byte next = _ImageData[currByte++];

                    // calculate the factors
                    int factor1 = (int)next / 16;
                    int factor2 = (int)next % 16;

                    // is the factor greater than 0?
                    if (factor1 > 0)
                    {
                        // combine the colors
                        Color color = CombineColors(m_Colours[(int)_ImageData[currByte++]].Pixel, m_image.GetPixel(curx, cury), factor1);

                        // color the pixel
                        m_image.SetPixel(curx, cury, color);

                        // flag that this pixel is used (for VD save)
                        m_VDImageData[curx, cury] = "1";

                        // get the next coordinate in the image
                        NextCoordinate(ref curx, ref cury, m_width, m_height);
                    }

                    // scan the other bytes
                    for (byte i = (byte)((uint)curr - 128U); i > (byte)0; i--)
                    {
                        // get the pixel color
                        Color pixel = m_Colours[(int)_ImageData[currByte++]].Pixel;

                        // set the color to the image
                        m_image.SetPixel(curx, cury, pixel);

                        // flag that this pixel is used (for VD save)
                        m_VDImageData[curx, cury] = "1";

                        // move to the next coordinate in the image
                        NextCoordinate(ref curx, ref cury, m_width, m_height);
                    }

                    // is the second factor greater than 0?
                    if (factor2 > 0)
                    {
                        // combine the colors
                        Color color = CombineColors(m_Colours[(int)_ImageData[currByte++]].Pixel, m_image.GetPixel(curx, cury), factor2);

                        // color the pixel
                        m_image.SetPixel(curx, cury, color);

                        // flag that this pixel is used (for VD save)
                        m_VDImageData[curx, cury] = "1";

                        // get the next coordinate in the image
                        NextCoordinate(ref curx, ref cury, m_width, m_height);
                    }
                }
            }
        }
        /// <summary>
        /// Floodfill gray pixels in an image
        /// </summary>
        /// <param name="bmp">Image to parse</param>
        /// <param name="pt">Starting point (must be gray)</param>
        /// <param name="levels">Hue colors table</param>
        /// <param name="handled">List of all the pixels already done</param>
        private static void FloodFillGrayPixels(DirectBitmap bmp, Point pt, List <Color> levels, ref List <Point> handled)
        {
            // create a points queue
            Queue <Point> q = new Queue <Point>();

            // add the current point to the queue
            q.Enqueue(pt);

            // keep going until the queue is empty
            while (q.Count > 0)
            {
                // get the first point
                Point n = q.Dequeue();

                // get the color for the current pixel
                Color currColor = bmp.GetPixel(n.X, n.Y);

                // if the pixel is not gray or is already been handled, we can get out (we also skil black and transparent colors)
                if (!(currColor.R == currColor.G && currColor.R == currColor.B) || ColorMatch(currColor, Color.Black) || ColorMatch(currColor, Color.FromArgb(0, 0, 0, 0)) || handled.Contains(pt))
                {
                    return;
                }

                // get the next point
                Point w = n, e = new Point(n.X + 1, n.Y);

                // keep going until the colors are within the threshold or we reach the beginning of the line
                while ((w.X >= 0) && IsPixelGrayScale(bmp.GetPixel(w.X, w.Y)))
                {
                    // replace the pixel color
                    bmp.SetPixel(w.X, w.Y, levels[bmp.GetPixel(w.X, w.Y).B]);

                    // add the pixel to the list of the handled ones
                    if (!handled.Contains(w))
                    {
                        handled.Add(w);
                    }

                    // if the previous pixel is grayscale, we put that in the queue
                    if ((w.Y > 0) && IsPixelGrayScale(bmp.GetPixel(w.X, w.Y - 1)))
                    {
                        q.Enqueue(new Point(w.X, w.Y - 1));
                    }

                    // if the next pixel is grayscale, we put that in the queue
                    if ((w.Y < bmp.Height - 1) && IsPixelGrayScale(bmp.GetPixel(w.X, w.Y + 1)))
                    {
                        q.Enqueue(new Point(w.X, w.Y + 1));
                    }

                    // move backwards in the line
                    w.X--;
                }

                // keep going until the colors are within the threshold or we reach the end of the line
                while ((e.X <= bmp.Width - 1) && IsPixelGrayScale(bmp.GetPixel(e.X, e.Y)))
                {
                    // replace the pixel color
                    bmp.SetPixel(e.X, e.Y, levels[bmp.GetPixel(e.X, e.Y).B]);

                    // add the pixel to the list of the handled ones
                    if (!handled.Contains(e))
                    {
                        handled.Add(e);
                    }

                    // check the pixel on the previous line, if it matches, we add it to the queue
                    if ((e.Y > 0) && IsPixelGrayScale(bmp.GetPixel(e.X, e.Y - 1)))
                    {
                        q.Enqueue(new Point(e.X, e.Y - 1));
                    }

                    // check the pixel in the next line, if it matches, we add it to the queue
                    if ((e.Y < bmp.Height - 1) && IsPixelGrayScale(bmp.GetPixel(e.X, e.Y + 1)))
                    {
                        q.Enqueue(new Point(e.X, e.Y + 1));
                    }

                    // move forward along the line
                    e.X++;
                }
            }
        }