private void Render(Surface src, Surface dst, Rectangle rect, ArgusColor bgColor)
        {
            HsvColorF hsvBg = bgColor;

            for (int y = rect.Top; y < rect.Bottom; y++)
            {
                for (int x = rect.Left; x < rect.Right; x++)
                {
                    ArgusColor px = src[x, y];
                    if (Math.Abs(px.R - bgColor.R) < this._tolRGB && Math.Abs(px.G - bgColor.G) < this._tolRGB && Math.Abs(px.B - bgColor.B) < this._tolRGB)
                    {
                        dst[x, y] = ColorBgra.FromUInt32(0);
                    }
                    else
                    {
                        HsvColorF hsv  = px;
                        double    dHue = Math.Abs(hsv.Hue - hsvBg.Hue);
                        if (dHue > 180)
                        {
                            dHue = 360 - dHue;
                        }

                        if (dHue < this._tolHue && Math.Abs(hsv.Saturation - hsvBg.Saturation) < this._tolSat && Math.Abs(hsv.Value - hsvBg.Value) < this._tolVal)
                        {
                            dst[x, y] = ColorBgra.FromUInt32(0);
                        }
                        else
                        {
                            dst[x, y] = px.ReverseBlend(bgColor);
                        }
                    }
                }
            }
        }
        protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs)
        {
            var newBgSource = (BackgroundSources)newToken.GetProperty <StaticListChoiceProperty>(PropertyNames.BackgroundSource).Value;

            this._tolRGB       = newToken.GetProperty <Int32Property>(PropertyNames.ToleranceRGB).Value;
            this._tolHue       = newToken.GetProperty <Int32Property>(PropertyNames.ToleranceHue).Value;
            this._tolSat       = newToken.GetProperty <Int32Property>(PropertyNames.ToleranceSat).Value;
            this._tolVal       = newToken.GetProperty <Int32Property>(PropertyNames.ToleranceVal).Value;
            this._domColMaxDev = newToken.GetProperty <Int32Property>(PropertyNames.DominantColorMaxDeviation).Value;

            if (newBgSource != this._bgSource && (newBgSource == BackgroundSources.ClipboardAverage || newBgSource == BackgroundSources.ClipboardDominant))
            {
                this._clipboardSurface = Utils.GetSurfaceFromClipboard();
            }

            this._bgSource = newBgSource;

            if (this._bgSource == BackgroundSources.DominantColor)
            {
                this._taskBGColor = srcArgs.Surface.GetDominantColorAsync((byte)this._domColMaxDev, 100, this.EnvironmentParameters.GetSelectionScanlines(), this);
            }
            else if (this._bgSource == BackgroundSources.ClipboardDominant)
            {
                this._taskBGColor = this._clipboardSurface?.GetDominantColorAsync((byte)this._domColMaxDev, 100, null, this) ?? Task.FromResult <ArgusColor>(this.EnvironmentParameters.PrimaryColor);
            }
            else if (this._bgSource == BackgroundSources.ClipboardAverage)
            {
                this._taskBGColor = Task.Run(() => { return(this._clipboardSurface?.GetMeanAndStdDeviation(null, this).First ?? this.EnvironmentParameters.PrimaryColor); });
            }
            else if (this._bgSource == BackgroundSources.ColorWheel)
            {
                this._taskBGColor = Task.FromResult <ArgusColor>(ArgusColor.FromRGB(newToken.GetProperty <Int32Property>(PropertyNames.ColorWheel).Value));
            }
            else if (this._bgSource == BackgroundSources.SecondaryColor)
            {
                this._taskBGColor = Task.FromResult <ArgusColor>(this.EnvironmentParameters.SecondaryColor);
            }
            else
            {
                this._taskBGColor = Task.FromResult <ArgusColor>(this.EnvironmentParameters.PrimaryColor);
            }

            base.OnSetRenderInfo(newToken, dstArgs, srcArgs);
        }