Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageBase{TColor, TPacked}"/> class.
        /// </summary>
        /// <param name="other">
        /// The other <see cref="ImageBase{TColor, TPacked}"/> to create this instance from.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown if the given <see cref="ImageBase{TColor, TPacked}"/> is null.
        /// </exception>
        protected ImageBase(ImageBase <TColor, TPacked> other)
        {
            Guard.NotNull(other, nameof(other), "Other image cannot be null.");

            this.Width  = other.Width;
            this.Height = other.Height;
            this.CopyProperties(other);

            // Copy the pixels. Unsafe.CopyBlock gives us a nice speed boost here.
            this.pixelBuffer = new TColor[this.Width * this.Height];
            using (PixelAccessor <TColor, TPacked> sourcePixels = other.Lock())
                using (PixelAccessor <TColor, TPacked> target = this.Lock())
                {
                    sourcePixels.CopyImage(target);
                }
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageBase{TColor}"/> class.
        /// </summary>
        /// <param name="other">
        /// The other <see cref="ImageBase{TColor}"/> to create this instance from.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown if the given <see cref="ImageBase{TColor}"/> is null.
        /// </exception>
        protected ImageBase(ImageBase <TColor> other)
        {
            Guard.NotNull(other, nameof(other), "Other image cannot be null.");

            this.Width  = other.Width;
            this.Height = other.Height;
            this.CopyProperties(other);

            // Rent then copy the pixels. Unsafe.CopyBlock gives us a nice speed boost here.
            this.RentPixels();
            using (PixelAccessor <TColor> sourcePixels = other.Lock())
                using (PixelAccessor <TColor> target = this.Lock())
                {
                    // Check we can do this without crashing
                    sourcePixels.CopyTo(target);
                }
        }
Example #3
0
        /// <summary>
        /// Finds the bounding rectangle based on the first instance of any color component other
        /// than the given one.
        /// </summary>
        /// <typeparam name="TColor">The pixel format.</typeparam>
        /// <param name="bitmap">The <see cref="Image"/> 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 <TColor>(ImageBase <TColor> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
            where TColor : struct, IPixel <TColor>
        {
            int   width       = bitmap.Width;
            int   height      = bitmap.Height;
            Point topLeft     = default(Point);
            Point bottomRight = default(Point);

            Func <PixelAccessor <TColor>, 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;
            }

            Func <PixelAccessor <TColor>, int> getMinY = 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);
            };

            Func <PixelAccessor <TColor>, int> getMaxY = 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);
            };

            Func <PixelAccessor <TColor>, int> getMinX = 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);
            };

            Func <PixelAccessor <TColor>, int> getMaxX = 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);
            };

            using (PixelAccessor <TColor> bitmapPixels = bitmap.Lock())
            {
                topLeft.Y     = getMinY(bitmapPixels);
                topLeft.X     = getMinX(bitmapPixels);
                bottomRight.Y = (getMaxY(bitmapPixels) + 1).Clamp(0, height);
                bottomRight.X = (getMaxX(bitmapPixels) + 1).Clamp(0, width);
            }

            return(GetBoundingRectangle(topLeft, bottomRight));
        }