Exemple #1
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>
        /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></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, TPacked>(ImageBase <TColor, TPacked> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
            where TColor : struct, IPackedPixel <TPacked>
            where TPacked : struct, IEquatable <TPacked>
        {
            const float Epsilon     = .00001f;
            int         width       = bitmap.Width;
            int         height      = bitmap.Height;
            Point       topLeft     = default(Point);
            Point       bottomRight = default(Point);

            Func <PixelAccessor <TColor, TPacked>, int, int, float, bool> delegateFunc;

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

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

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

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

            Func <PixelAccessor <TColor, TPacked>, 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, TPacked>, 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, TPacked>, 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, TPacked>, 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, TPacked> 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));
        }
Exemple #2
0
        /// <summary>
        /// Copies the pixels to another <see cref="PixelAccessor{TColor}"/> of the same size.
        /// </summary>
        /// <param name="target">The target pixel buffer accessor.</param>
        internal void CopyTo(PixelAccessor <TColor> target)
        {
            uint byteCount = (uint)(this.Width * this.Height * Unsafe.SizeOf <TColor>());

            Unsafe.CopyBlock(target.pixelsBase, this.pixelsBase, byteCount);
        }
Exemple #3
0
 /// <summary>
 /// Copies an entire image.
 /// </summary>
 /// <param name="target">The target pixel buffer accessor.</param>
 public void CopyImage(PixelAccessor <TColor, TPacked> target)
 {
     this.CopyBlock(0, 0, target, 0, 0, target.Width * target.Height);
 }
 /// <summary>
 /// Copies the pixels to another <see cref="PixelAccessor{TPixel}"/> of the same size.
 /// </summary>
 /// <param name="target">The target pixel buffer accessor.</param>
 internal void CopyTo(PixelAccessor <TPixel> target)
 {
     SpanHelper.Copy(this.pixelBuffer.Span, target.pixelBuffer.Span);
 }