public void Invoke(int y) { Rgba32 rgb = default; Span <TPixel> pixelRow = this.source.GetPixelRowSpan(y); for (int x = this.startX; x < this.endX; x++) { TPixel pixel = pixelRow[x]; pixel.ToRgba32(ref rgb); var x1 = Math.Max(x - this.startX - this.clusterSize + 1, 0); var x2 = Math.Min(x - this.startX + this.clusterSize + 1, this.bounds.Width - 1); var y1 = Math.Max(y - this.startY - this.clusterSize + 1, 0); var y2 = Math.Min(y - this.startY + this.clusterSize + 1, this.bounds.Height - 1); var count = (uint)((x2 - x1) * (y2 - y1)); var sum = (long)Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], long.MaxValue); if ((rgb.R + rgb.G + rgb.B) * count <= sum * this.thresholdLimit) { this.source[x, y] = this.lower; } else { this.source[x, y] = this.upper; } } }
private static TPixel GetBottomRightColor() { TPixel bottomRightColor = default; bottomRightColor.FromVector4(new Vector4(1f, 0f, 1f, 0.5f)); return(bottomRightColor); }
/// <summary> /// Add a color into the tree /// </summary> /// <param name="pixel">The color</param> /// <param name="colorBits">The number of significant color bits</param> /// <param name="level">The level in the tree</param> /// <param name="octree">The tree to which this node belongs</param> /// <param name="buffer">The buffer array.</param> public void AddColor(TPixel pixel, int colorBits, int level, Octree octree, byte[] buffer) { // Update the color information if this is a leaf if (this.leaf) { this.Increment(pixel, buffer); // Setup the previous node octree.TrackPrevious(this); } else { // Go to the next level down in the tree int shift = 7 - level; pixel.ToXyzwBytes(buffer, 0); int index = ((buffer[2] & Mask[level]) >> (shift - 2)) | ((buffer[1] & Mask[level]) >> (shift - 1)) | ((buffer[0] & Mask[level]) >> shift); OctreeNode child = this.children[index]; if (child == null) { // Create a new child node and store it in the array child = new OctreeNode(level + 1, colorBits, octree); this.children[index] = child; } // Add the color to the child node child.AddColor(pixel, colorBits, level + 1, octree, buffer); } }
/// <summary> /// Return the palette index for the passed color /// </summary> /// <param name="pixel">The pixel data.</param> /// <param name="level">The level.</param> /// <param name="buffer">The buffer array.</param> /// <returns> /// The <see cref="int"/> representing the index of the pixel in the palette. /// </returns> public int GetPaletteIndex(TPixel pixel, int level, byte[] buffer) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; pixel.ToXyzwBytes(buffer, 0); int pixelIndex = ((buffer[2] & Mask[level]) >> (shift - 2)) | ((buffer[1] & Mask[level]) >> (shift - 1)) | ((buffer[0] & Mask[level]) >> shift); if (this.children[pixelIndex] != null) { index = this.children[pixelIndex].GetPaletteIndex(pixel, level + 1, buffer); } else { throw new Exception($"Cannot retrive a pixel at the given index {pixelIndex}."); } } return(index); }
/// <summary> /// Traverse the tree, building up the color palette /// </summary> /// <param name="palette">The palette</param> /// <param name="index">The current palette index</param> public void ConstructPalette(TPixel[] palette, ref int index) { if (this.leaf) { // This seems faster than using Vector4 byte r = (this.red / this.pixelCount).ToByte(); byte g = (this.green / this.pixelCount).ToByte(); byte b = (this.blue / this.pixelCount).ToByte(); // And set the color of the palette entry TPixel pixel = default; pixel.PackFromRgba32(new Rgba32(r, g, b, 255)); palette[index] = pixel; // Consume the next palette index this.paletteIndex = index++; } else { // Loop through children looking for leaves for (int i = 0; i < 8; i++) { if (this.children[i] != null) { this.children[i].ConstructPalette(palette, ref index); } } } }
/// <summary> /// Return the palette index for the passed color /// </summary> /// <param name="pixel">The pixel data.</param> /// <param name="level">The level.</param> /// <param name="rgba">The color to map to.</param> /// <returns> /// The <see cref="int"/> representing the index of the pixel in the palette. /// </returns> public int GetPaletteIndex(TPixel pixel, int level, ref Rgba32 rgba) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; pixel.ToRgba32(ref rgba); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); if (this.children[pixelIndex] != null) { index = this.children[pixelIndex].GetPaletteIndex(pixel, level + 1, ref rgba); } else { throw new Exception($"Cannot retrive a pixel at the given index {pixelIndex}."); } } return(index); }
/// <summary> /// Add a color into the tree /// </summary> /// <param name="pixel">The pixel color</param> /// <param name="colorBits">The number of significant color bits</param> /// <param name="level">The level in the tree</param> /// <param name="octree">The tree to which this node belongs</param> public void AddColor(ref TPixel pixel, int colorBits, int level, Octree octree) { // Update the color information if this is a leaf if (this.leaf) { this.Increment(ref pixel); // Setup the previous node octree.TrackPrevious(this); } else { // Go to the next level down in the tree int shift = 7 - level; Rgba32 rgba = default; pixel.ToRgba32(ref rgba); int index = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); OctreeNode child = this.children[index]; if (child is null) { // Create a new child node and store it in the array child = new OctreeNode(level + 1, colorBits, octree); this.children[index] = child; } // Add the color to the child node child.AddColor(ref pixel, colorBits, level + 1, octree); } }
public int GetPaletteIndex(ref TPixel pixel, int level) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; Rgba32 rgba = default; pixel.ToRgba32(ref rgba); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); OctreeNode child = this.children[pixelIndex]; if (child != null) { index = child.GetPaletteIndex(ref pixel, level + 1); } else { throw new Exception($"Cannot retrieve a pixel at the given index {pixelIndex}."); } } return(index); }
/// <summary> Initialize local ressources for all constructors. </summary> private void InitializeSmeRessources() { _focusedColorPixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, XrwTheme.FocusedColor); Enter += HandleEnterDefault; Leave += HandleLeaveDefault; }
/// <summary> /// Fills the bottom right quadrant with all the colors producible by converting iterating over a uint and unpacking it. /// A better algorithm could be used but it works /// </summary> private static void Rainbow(Buffer2D <TPixel> pixels) { int left = pixels.Width / 2; int right = pixels.Width; int top = pixels.Height / 2; int bottom = pixels.Height; int pixelCount = left * top; uint stepsPerPixel = (uint)(uint.MaxValue / pixelCount); TPixel c = default; var t = new Rgba32(0); for (int x = left; x < right; x++) { for (int y = top; y < bottom; y++) { t.PackedValue += stepsPerPixel; var v = t.ToVector4(); // v.W = (x - left) / (float)left; c.FromVector4(v); pixels[x, y] = c; } } }
public override Image <TPixel> GetImage() { var result = new Image <TPixel>(this.Configuration, this.Width, this.Height); TPixel topLeftColor = Color.Red.ToPixel <TPixel>(); TPixel topRightColor = Color.Green.ToPixel <TPixel>(); TPixel bottomLeftColor = Color.Blue.ToPixel <TPixel>(); // Transparent purple: TPixel bottomRightColor = default; bottomRightColor.FromVector4(new Vector4(1f, 0f, 1f, 0.5f)); int midY = this.Height / 2; int midX = this.Width / 2; for (int y = 0; y < midY; y++) { Span <TPixel> row = result.GetPixelRowSpan(y); row.Slice(0, midX).Fill(topLeftColor); row.Slice(midX, this.Width - midX).Fill(topRightColor); } for (int y = midY; y < this.Height; y++) { Span <TPixel> row = result.GetPixelRowSpan(y); row.Slice(0, midX).Fill(bottomLeftColor); row.Slice(midX, this.Width - midX).Fill(bottomRightColor); } return(result); }
/// <summary> /// Increment the pixel count and add to the color information /// </summary> /// <param name="pixel">The pixel to add.</param> /// <param name="buffer">The buffer array.</param> public void Increment(TPixel pixel, byte[] buffer) { pixel.ToXyzwBytes(buffer, 0); this.pixelCount++; this.red += buffer[0]; this.green += buffer[1]; this.blue += buffer[2]; }
public TPixel ToPixel <TPixel>() where TPixel : struct, IPixel <TPixel> { TPixel pixel = default; pixel.FromRgba64(this.data); return(pixel); }
public void Increment(ref TPixel pixel, ref Rgba32 rgba) { pixel.ToRgba32(ref rgba); this.pixelCount++; this.red += rgba.R; this.green += rgba.G; this.blue += rgba.B; }
/// <summary> /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> private static void AotCompileDithering <TPixel>() where TPixel : struct, IPixel <TPixel> { var test = new FloydSteinbergDiffuser(); TPixel pixel = default; test.Dither(new ImageFrame <TPixel>(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); }
public override Image <TPixel> GetImage() { Image <TPixel> image = base.GetImage(); TPixel color = default(TPixel); color.PackFromBytes(this.r, this.g, this.b, this.a); return(image.Fill(color)); }
/// <summary> /// Initializes a new instance of the <see cref="Octree"/> class. /// </summary> /// <param name="maxColorBits"> /// The maximum number of significant bits in the image /// </param> public Octree(int maxColorBits) { this.maxColorBits = maxColorBits; this.Leaves = 0; this.ReducibleNodes = new OctreeNode[9]; this.root = new OctreeNode(0, this.maxColorBits, this); this.previousColor = default; this.previousNode = null; }
public override Image <TPixel> GetImage() { Image <TPixel> image = base.GetImage(); TPixel color = default(TPixel); color.FromRgba32(new Rgba32(this.r, this.g, this.b, this.a)); image.Mutate(x => x.Fill(color)); return(image); }
public void FloodFill(System.Drawing.Point location, TPixel anchorColor, TPixel replecedColor) { int width = this.Width; int height = this.Height; if (location.X < 0 || location.X >= width || location.Y < 0 || location.Y >= height) { return; } if (anchorColor == replecedColor) { return; } if (this[location.Y, location.X] != anchorColor) { return; } Stack <System.Drawing.Point> points = new Stack <System.Drawing.Point>(); points.Push(location); int ww = width - 1; int hh = height - 1; while (points.Count > 0) { System.Drawing.Point p = points.Pop(); this[p.Y, p.X] = replecedColor; if (p.X > 0 && this[p.Y, p.X - 1] == anchorColor) { this[p.Y, p.X - 1] = replecedColor; points.Push(new System.Drawing.Point(p.X - 1, p.Y)); } if (p.X < ww && this[p.Y, p.X + 1] == anchorColor) { this[p.Y, p.X + 1] = replecedColor; points.Push(new System.Drawing.Point(p.X + 1, p.Y)); } if (p.Y > 0 && this[p.Y - 1, p.X] == anchorColor) { this[p.Y - 1, p.X] = replecedColor; points.Push(new System.Drawing.Point(p.X, p.Y - 1)); } if (p.Y < hh && this[p.Y + 1, p.X] == anchorColor) { this[p.Y + 1, p.X] = replecedColor; points.Push(new System.Drawing.Point(p.X, p.Y + 1)); } } }
public unsafe void Fill(TPixel pixel) { TPixel *p = this.Start; TPixel *end = p + this.Length; while (p != end) { *p = pixel; p++; } }
public static unsafe void FillImage(ImageChannel <TPixel> img, TPixel value) { int step = img.Step; TPixel *start = (TPixel *)img.StartIntPtr; TPixel *end = start += img.Length * img.Step; while (start != end) { *start = value; start += step; } }
/// <summary> Initialize local ressources for all constructors. </summary> private void InitializeXrwVisibleRectObjRessources() { _gc = X11lib.XCreateGC(_display, _window, 0, IntPtr.Zero); if (_gc == IntPtr.Zero) { throw new OperationCanceledException("Failed to create graphics context."); } _backgroundColorPixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, XrwTheme.BackGroundColor); _darkShadowColorPixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, XrwTheme.DarkShadowColor); _lightShadowColorPixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, XrwTheme.LightShadowColor); }
/// <summary> Initialize local ressources for all constructors. </summary> private void InitializeCommandRessources() { _frameWidth = XrwTheme.InteractingFrameWidth; _frameType = (TFrameTypeExt)XrwTheme.InteractingFrameType; _focusedColorPixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, XrwTheme.FocusedColor); Enter += this.HandleEnterDefault; Leave += this.HandleLeaveDefault; ButtonPress += this.HandleButtonPressDefault; ButtonRelease += this.HandleButtonReleaseDefault; }
static void VerifyAllRowsAreUnicolor(Image <TPixel> image) { for (int y = 0; y < image.Height; y++) { Span <TPixel> row = image.GetPixelRowSpan(y); TPixel firstColorOfRow = row[0]; foreach (TPixel p in row) { Assert.Equal(firstColorOfRow, p); } } }
public static XColor NewXColor(TPixel pixel, ushort r, ushort g, ushort b, sbyte flags, sbyte pad) { XColor result = new XColor(); result.pixel = pixel; result.red = r; result.green = g; result.blue = b; result.flags = flags; result.pad = pad; return(result); }
/// <summary> /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> private static void AotCompileDithering <TPixel>() where TPixel : unmanaged, IPixel <TPixel> { ErrorDither errorDither = ErrorDither.FloydSteinberg; OrderedDither orderedDither = OrderedDither.Bayer2x2; TPixel pixel = default; using (var image = new ImageFrame <TPixel>(Configuration.Default, 1, 1)) { errorDither.Dither(image, image.Bounds(), pixel, pixel, 0, 0, 0); orderedDither.Dither(pixel, 0, 0, 0, 0); } }
public unsafe void Replace(TPixel pixel, TPixel replaced) { TPixel *p = this.Start; TPixel *end = p + this.Length; while (p != end) { if (*p == pixel) { *p = replaced; } p++; } }
/// <summary> Initialize local ressources for all constructors. </summary> /// <param name="assignedPosition"> The position of the top left top corner assigned by the window manager (for shell widgets) or geometry management (by non-shell widgets). Passed as reference to avoid structure copy constructor calls. <see cref="TPoint"/> </param> public void InitializeTransientShellResources(ref TPoint offset) { /* Get the colors black and white. */ TPixel black = X11lib.XBlackPixel(_display, _screenNumber); /* get color black */ TPixel white = X11lib.XWhitePixel(_display, _screenNumber); /* get color white */ /* Once the display is initialized, create the window. * It will have the foreground white and background black */ _window = X11lib.XCreateSimpleWindow(_display, X11lib.XDefaultRootWindow(_display), (TInt)offset.X, (TInt)offset.Y, (TUint)_assignedSize.Width, (TUint)_assignedSize.Height, 0, 0, black); if (_window == IntPtr.Zero) { Console.WriteLine(CLASS_NAME + "::InitializeTransientShellResources () ERROR. Can not create transient shell."); return; } X11lib.XSelectInput(_display, _window, EventMask.StructureNotifyMask | EventMask.ExposureMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.EnterWindowMask | EventMask.LeaveWindowMask | EventMask.PointerMotionMask | EventMask.FocusChangeMask | EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.SubstructureNotifyMask); _hasOwnWindow = true; /* Hook the closing event from windows manager. */ _wmDeleteMessage = X11lib.XInternAtom(_display, "WM_DELETE_WINDOW", false); if (X11lib.XSetWMProtocols(_display, _window, ref _wmDeleteMessage, (X11.TInt) 1) == 0) { Console.WriteLine(CLASS_NAME + "::InitializeTransientShellResources () WARNING: Failed to register 'WM_DELETE_WINDOW' event."); } X11lib.XSetTransientForHint(_display, _window, Parent.Window); /* Recreate the foreground Graphics Context with. */ if (_gc != IntPtr.Zero) { if (XrwApplicationSettings.VERBOSE_OUTPUT_TO_CONSOLE) { Console.WriteLine(CLASS_NAME + "::InitializeTransientShellResources () Replace the foreground GC."); } X11lib.XFreeGC(_display, _gc); _gc = IntPtr.Zero; } _gc = X11lib.XCreateGC(_display, _window, 0, IntPtr.Zero); X11lib.XSetForeground(_display, _gc, white); }
public RowOperation( Rectangle bounds, ImageFrame <TPixel> source, TPixel upper, TPixel lower, byte threshold, bool isAlphaOnly) { this.source = source; this.upper = upper; this.lower = lower; this.threshold = threshold; this.minX = bounds.X; this.maxX = bounds.Right; this.isAlphaOnly = isAlphaOnly; }
public TPixel[] Palletize(int colorCount) { while (this.Leaves > colorCount - 1) { this.Reduce(); } // Now palletize the nodes var palette = new TPixel[colorCount]; int paletteIndex = 0; this.root.ConstructPalette(palette, ref paletteIndex); // And return the palette return(palette); }