public void ChangeColorOfOtherBucketToTheSameOfThisOne(ColorBucket otherBucket) { //Debug.Log("Change"); soundWhenPressed.Play(); otherBucket.image.enabled = true; otherBucket.bucketColor = this.bucketColor; }
internal ColorBucket RemoveFirstBucket() { if (buckets.Count == 0) { return(null); } ColorBucket result = buckets[0]; buckets.RemoveFirst(); return(result); }
internal bool SplitBuckets(IAsyncContext context, ref int index) { bool splitOccurred = false; // saving length because we add new buckets during the iteration int endIndex = buckets.Count; if (index >= endIndex) { index = 0; } while (index < endIndex) { ColorBucket currentBucket = buckets[index]; Debug.Assert(currentBucket.Count > 0, "Empty bucket"); Debug.Assert(!currentBucket.IsSingleColor); if (context.IsCancellationRequested) { return(false); } splitOccurred = true; // on equal distance splitting on the green range in the first place because of human perception if (currentBucket.RangeG >= currentBucket.RangeR && currentBucket.RangeG >= currentBucket.RangeB) { currentBucket.Split(ColorComponent.G, this, ref index, ref endIndex); } else if (currentBucket.RangeR >= currentBucket.RangeB) { currentBucket.Split(ColorComponent.R, this, ref index, ref endIndex); } else { currentBucket.Split(ColorComponent.B, this, ref index, ref endIndex); } context.Progress?.SetProgressValue(ColorsCount); // Stopping if we reached maxColors. Note that Split may increase ColorsCount. if (ColorsCount == maxColors) { return(false); } } return(splitOccurred); }
public FloodFillDemo() { // _magicWandConfigs = new MagicWandConfigGroup(); BackgroundColor = Color.White; _defaultImg = new MemBitmap(400, 300); AggPainter p = AggPainter.Create(_defaultImg); p.Clear(Color.White); p.FillColor = Color.Black; p.FillEllipse(20, 20, 30, 30); for (int i = 0; i < 20; i++) { p.StrokeColor = Color.Black; p.DrawEllipse(i * 10, i * 10, 20, 20); } // this.PixelSize = 32; this.Gamma = 1; _tolerance = 30; _floodFill = new ColorBucket(Color.Red, _tolerance); _magicWand = new MagicWand(_tolerance); // //_lionPng = MemBitmapExtensions.LoadBitmap("../Data/lion1_v2_2.png"); //_lionPng = MemBitmapExtensions.LoadBitmap("../Data/lion1_v2_4_1.png"); _lionPng = MemBitmapExt.LoadBitmap("../Data/lion1.png"); //_lionPng = MemBitmapExtensions.LoadBitmap("../Data/lion_1_v3_2.png"); //_lionPng = MemBitmapExtensions.LoadBitmap("../Data/glyph_a.png"); _starsPng = MemBitmapExt.LoadBitmap("../Data/stars.png"); _test_glyphs = MemBitmapExt.LoadBitmap("../Data/test_glyphs.png"); _rect01 = MemBitmapExt.LoadBitmap("../Data/rect01.png"); //_v_shape = MemBitmapExtensions.LoadBitmap("../Data/shape_v.png"); //_v_shape = MemBitmapExtensions.LoadBitmap("../Data/shape_v3.png"); _bmpToFillOn = _defaultImg; OutlineReconstruction = true; WithOutlineSimplifier = true; }
public void Dispose() => root = null;
public Color32[] GeneratePalette(IAsyncContext context) { // Occurs when bitmap is completely transparent if (root.Count == 0) { Debug.Assert(hasTransparency); return(new Color32[1]); } Color32[] result; if (root.IsSingleColor) { result = new Color32[hasTransparency ? 2 : 1]; result[0] = root.ToColor(); return(result); } context.Progress?.New(DrawingOperation.GeneratingPalette, MaxActualColors, 1); var buckets = new ColorBucketCollection(MaxActualColors); buckets.AddBucket(root); // splitting the initial bucket until no more split can be done or desired color amount is reached int startIndex = 0; while (buckets.ColorsCount < MaxActualColors) { if (buckets.SplitBuckets(context, ref startIndex)) { startIndex = 0; } else { break; } } // finalizing colors and continuing splitting if some buckets map to the same colors while (buckets.FinalColorsCount < MaxActualColors) { ColorBucket first = buckets.RemoveFirstBucket(); if (first == null) { break; } if (startIndex > 0) { startIndex -= 1; } if (!buckets.AddFinalColor(first.ToColor())) { buckets.SplitBuckets(context, ref startIndex); } } if (context.IsCancellationRequested) { return(null); } Debug.Assert(buckets.FinalColorsCount <= MaxActualColors); result = new Color32[buckets.FinalColorsCount + (hasTransparency ? 1 : 0)]; buckets.CopyFinalColorsTo(result); context.Progress?.Complete(); // If transparent color is needed, then it will be automatically the last color in the result return(result); }
public void Initialize(int requestedColors, IBitmapData source) { maxColors = requestedColors; root = new ColorBucket(source.Width * source.Height); }
public void ReplaceBucket(int index, ColorBucket bucket) => buckets[index] = bucket;
internal void AddBucket(ColorBucket item) { Debug.Assert(!item.IsSingleColor, "Single color should be added to final colors"); buckets.Add(item); }
internal void Split(ColorComponent component, ColorBucketCollection buckets, ref int index, ref int endIndex) { Debug.Assert(colors.Count > 1); // always sorting by all of the components so then we can eliminate same color groups easily switch (component) { case ColorComponent.R: colors.Sort(redSorter); break; case ColorComponent.G: colors.Sort(greenSorter); break; case ColorComponent.B: colors.Sort(blueSorter); break; } int medianIndex = colors.Count >> 1; // single color check is correct because we sorted by all of the components bool isLeftSingleColor = colors[0] == colors[medianIndex - 1]; bool isRightSingleColor = colors[medianIndex] == colors[colors.Count - 1]; ColorBucket left = isLeftSingleColor ? null : new ColorBucket(medianIndex); ColorBucket right = isRightSingleColor ? null : new ColorBucket(colors.Count - medianIndex); // populating the left and right buckets int from = isLeftSingleColor ? (isRightSingleColor ? Int32.MaxValue : medianIndex) : 0; int to = isRightSingleColor ? (isLeftSingleColor ? 0 : medianIndex) : colors.Count; for (int i = from; i < to; i++) { if (i < medianIndex) { left.AddColor(colors[i]); } else { right.AddColor(colors[i]); } } if (isLeftSingleColor) { buckets.AddFinalColor(colors[0]); // if none of the halves could be added, we remove the current bucket and reduce the number of buckets to scan if (isRightSingleColor) { buckets.AddFinalColor(colors[medianIndex]); buckets.RemoveBucket(index); endIndex -= 1; return; } // the right half is assigned back to the original position buckets.ReplaceBucket(index, right); index += 1; return; } // the left half is assigned back to the original position buckets.ReplaceBucket(index, left); index += 1; if (isRightSingleColor) { buckets.AddFinalColor(colors[medianIndex]); return; } // the right half is added as a new bucket buckets.AddBucket(right); }