Example #1
0
        /// <summary>
        /// Finds the bounding rectangle based on the first instance of any color component other
        /// than the given one.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="bitmap">The <see cref="Image{TPixel}"/> to search within.</param>
        /// <param name="componentValue">The color component value to remove.</param>
        /// <param name="channel">The <see cref="RgbaComponent"/> channel to test against.</param>
        /// <returns>
        /// The <see cref="Rectangle"/>.
        /// </returns>
        public static Rectangle GetFilteredBoundingRectangle <TPixel>(ImageFrame <TPixel> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
            where TPixel : struct, IPixel <TPixel>
        {
            int   width       = bitmap.Width;
            int   height      = bitmap.Height;
            Point topLeft     = default;
            Point bottomRight = default;

            Func <ImageFrame <TPixel>, int, int, float, bool> delegateFunc;

            // Determine which channel to check against
            switch (channel)
            {
            case RgbaComponent.R:
                delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon;
                break;

            case RgbaComponent.G:
                delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon;
                break;

            case RgbaComponent.B:
                delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon;
                break;

            default:
                delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon;
                break;
            }

            int GetMinY(ImageFrame <TPixel> pixels)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        if (delegateFunc(pixels, x, y, componentValue))
                        {
                            return(y);
                        }
                    }
                }

                return(0);
            }

            int GetMaxY(ImageFrame <TPixel> pixels)
            {
                for (int y = height - 1; y > -1; y--)
                {
                    for (int x = 0; x < width; x++)
                    {
                        if (delegateFunc(pixels, x, y, componentValue))
                        {
                            return(y);
                        }
                    }
                }

                return(height);
            }

            int GetMinX(ImageFrame <TPixel> pixels)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        if (delegateFunc(pixels, x, y, componentValue))
                        {
                            return(x);
                        }
                    }
                }

                return(0);
            }

            int GetMaxX(ImageFrame <TPixel> pixels)
            {
                for (int x = width - 1; x > -1; x--)
                {
                    for (int y = 0; y < height; y++)
                    {
                        if (delegateFunc(pixels, x, y, componentValue))
                        {
                            return(x);
                        }
                    }
                }

                return(height);
            }

            topLeft.Y     = GetMinY(bitmap);
            topLeft.X     = GetMinX(bitmap);
            bottomRight.Y = (GetMaxY(bitmap) + 1).Clamp(0, height);
            bottomRight.X = (GetMaxX(bitmap) + 1).Clamp(0, width);

            return(GetBoundingRectangle(topLeft, bottomRight));
        }