Beispiel #1
0
        /// <summary>
        /// Determine the real size of the layer, i.e., the smallest rectangle
        /// that includes all non-transparent pixels.
        /// </summary>
        private static Rectangle FindImageRectangle(Surface surface)
        {
            var rectPos = new Util.RectanglePosition
            {
                Left   = surface.Width,
                Top    = surface.Height,
                Right  = 0,
                Bottom = 0
            };

            unsafe
            {
                // Search for top non-transparent pixel
                bool fPixelFound = false;
                for (int y = 0; y < surface.Height; y++)
                {
                    if (ExpandImageRectangle(surface, y, 0, surface.Width, ref rectPos))
                    {
                        fPixelFound = true;
                        break;
                    }
                }

                // Narrow down the other dimensions of the image rectangle
                if (fPixelFound)
                {
                    // Search for bottom non-transparent pixel
                    for (int y = surface.Height - 1; y > rectPos.Bottom; y--)
                    {
                        if (ExpandImageRectangle(surface, y, 0, surface.Width, ref rectPos))
                        {
                            break;
                        }
                    }

                    // Search for left and right non-transparent pixels.  Because we
                    // scan horizontally, we can't just break, but we can examine fewer
                    // candidate pixels on the remaining rows.
                    for (int y = rectPos.Top + 1; y < rectPos.Bottom; y++)
                    {
                        ExpandImageRectangle(surface, y, 0, rectPos.Left, ref rectPos);
                        ExpandImageRectangle(surface, y, rectPos.Right + 1, surface.Width, ref rectPos);
                    }
                }
                else
                {
                    rectPos.Left = 0;
                    rectPos.Top  = 0;
                }
            }

            Debug.Assert(rectPos.Left <= rectPos.Right);
            Debug.Assert(rectPos.Top <= rectPos.Bottom);

            var result = new Rectangle(rectPos.Left, rectPos.Top,
                                       rectPos.Right - rectPos.Left + 1, rectPos.Bottom - rectPos.Top + 1);

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Check for non-transparent pixels in a row, or portion of a row.
        /// Expands the size of the image rectangle if any were found.
        /// </summary>
        /// <returns>True if non-transparent pixels were found, false otherwise.</returns>
        unsafe private static bool ExpandImageRectangle(Surface surface, int y,
                                                        int xStart, int xEnd, ref Util.RectanglePosition rectPos)
        {
            bool fPixelFound = false;

            ColorBgra *rowStart = surface.GetRowAddress(y);
            ColorBgra *pixel    = rowStart + xStart;

            for (int x = xStart; x < xEnd; x++)
            {
                if (pixel->A > 0)
                {
                    // Expand the rectangle to include the specified point.
                    if (x < rectPos.Left)
                    {
                        rectPos.Left = x;
                    }
                    if (x > rectPos.Right)
                    {
                        rectPos.Right = x;
                    }
                    if (y < rectPos.Top)
                    {
                        rectPos.Top = y;
                    }
                    if (y > rectPos.Bottom)
                    {
                        rectPos.Bottom = y;
                    }
                    fPixelFound = true;
                }
                pixel++;
            }

            return(fPixelFound);
        }