/// <summary> /// Saves the raw image pixels to a byte array in row-major order. /// </summary> /// <typeparam name="TPixel">The Pixel format.</typeparam> /// <param name="source">The source image</param> /// <returns>A copy of the pixel data as bytes from this frame.</returns> /// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception> public static byte[] SavePixelData <TPixel>(this ImageFrame <TPixel> source) where TPixel : struct, IPixel <TPixel> => MemoryMarshal.AsBytes(source.GetPixelSpan()).ToArray();
/// <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)); }
/// <summary> /// Determines the index of a specific <paramref name="frame"/> in the <seealso cref="ImageFrameCollection{TPixel}"/>. /// </summary> /// <param name="frame">The <seealso cref="ImageFrame{TPixel}"/> to locate in the <seealso cref="ImageFrameCollection{TPixel}"/>.</param> /// <returns>The index of item if found in the list; otherwise, -1.</returns> public int IndexOf(ImageFrame <TPixel> frame) => this.frames.IndexOf(frame);
/// <inheritdoc /> public override int IndexOf(ImageFrame frame) { return(frame is ImageFrame <TPixel> specific?this.IndexOf(specific) : -1); }
/// <summary> /// Determines whether the <seealso cref="ImageFrameCollection{TPixel}"/> contains the <paramref name="frame"/>. /// </summary> /// <param name="frame">The frame.</param> /// <returns> /// <c>true</c> if the <seealso cref="ImageFrameCollection{TPixel}"/> contains the specified frame; otherwise, <c>false</c>. /// </returns> public bool Contains(ImageFrame <TPixel> frame) => this.frames.Contains(frame);
/// <inheritdoc /> public override bool Contains(ImageFrame frame) => frame is ImageFrame <TPixel> specific && this.Contains(specific);