예제 #1
0
        /// <summary>
        /// Returns the nearest color in the palette
        /// </summary>
        public Color GetNearestColor(Color[] palette, Color color, ColorMatchMode colorMatchMode, float threshold, ColorEntry[] colorOperations, bool enableColorAdjustments, ColorAdjustments colorAdjustments)
        {
            if (colorOperations != null && colorOperations.Length > 0)
            {
                HSLColor hsl = ColorConversion.GetHSLFromRGB(color.r, color.g, color.b);

                for (int k = 0; k < colorOperations.Length; k++)
                {
                    switch (colorMatchMode)
                    {
                    case ColorMatchMode.RGB: {
                        float dr = colorOperations[k].color.r < color.r ? color.r - colorOperations[k].color.r : colorOperations[k].color.r - color.r;
                        float dg = colorOperations[k].color.g < color.g ? color.g - colorOperations[k].color.g : colorOperations[k].color.g - color.g;
                        float db = colorOperations[k].color.b < color.b ? color.b - colorOperations[k].color.b : colorOperations[k].color.b - color.b;
                        if (dr <= threshold && dg <= threshold && db <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Red: {
                        float dr = colorOperations[k].color.r < color.r ? color.r - colorOperations[k].color.r : colorOperations[k].color.r - color.r;
                        if (dr <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Green: {
                        float dg = colorOperations[k].color.g < color.g ? color.g - colorOperations[k].color.g : colorOperations[k].color.g - color.g;
                        if (dg <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Blue: {
                        float db = colorOperations[k].color.b < color.b ? color.b - colorOperations[k].color.b : colorOperations[k].color.b - color.b;
                        if (db <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.HSL: {
                        HSLColor hslOp = ColorConversion.GetHSLFromRGB(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float    dh    = hslOp.h < hsl.h ? hsl.h - hslOp.h : hslOp.h - hsl.h;
                        float    ds    = hslOp.s < hsl.s ? hsl.s - hslOp.s : hslOp.s - hsl.s;
                        float    dl    = hslOp.l < hsl.l ? hsl.l - hslOp.l : hslOp.l - hsl.l;
                        if (dh <= threshold && ds <= threshold && dl <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Hue: {
                        float hue = ColorConversion.GetHue(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float dh  = hue < hsl.h ? hsl.h - hue : hue - hsl.h;
                        if (dh <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Saturation: {
                        float sat = ColorConversion.GetSaturation(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float ds  = sat < hsl.s ? hsl.s - sat : sat - hsl.s;
                        if (ds <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Lightness: {
                        float l  = ColorConversion.GetLightness(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float dl = l < hsl.l ? hsl.l - l : l - hsl.l;
                        if (dl <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;
                    }
                }
            }

            float md      = float.MaxValue;
            Color nearest = color;

            switch (colorMatchMode)
            {
            case ColorMatchMode.RGB: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dr = (palette[c].r - color.r) * 0.299f;
                    float dg = (palette[c].g - color.g) * 0.587f;
                    float db = (palette[c].b - color.b) * 0.114f;
                    float d  = dr * dr + dg * dg + db * db;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Red: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dr = palette[c].r - color.r;
                    float d  = dr * dr;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Green: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dg = palette[c].g - color.g;
                    float d  = dg * dg;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Blue: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float db = palette[c].b - color.b;
                    float d  = db * db;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.HSL: {
                HSLColor hsl = ColorConversion.GetHSLFromRGB(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    HSLColor paletteHSL = ColorConversion.GetHSLFromRGB(palette[c].r, palette[c].g, palette[c].b);
                    float    dh         = (paletteHSL.h - hsl.h);
                    float    ds         = (paletteHSL.s - hsl.s);
                    float    dl         = (paletteHSL.l - hsl.l);
                    float    d          = dh * dh + ds * ds + dl * dl;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Hue: {
                float h = ColorConversion.GetHue(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteH = ColorConversion.GetHue(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteH - h);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Saturation: {
                float s = ColorConversion.GetSaturation(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteS = ColorConversion.GetSaturation(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteS - s);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Lightness: {
                float l = ColorConversion.GetLightness(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteL = ColorConversion.GetLightness(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteL - l);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;
            }
            nearest.a = color.a;
            color     = nearest;

            if (enableColorAdjustments)
            {
                if (colorAdjustments.applyLUT && colorAdjustments.LUT != null)
                {
                    color = ApplyLUT(color, colorAdjustments.LUT);
                }
                // vibrance
                float vibrance = colorAdjustments.vibrance;
                if (vibrance > 0)
                {
                    float maxComponent = color.r > color.g ? color.r : color.g;
                    maxComponent = color.b > maxComponent ? color.b : maxComponent;
                    float minComponent = color.r < color.g ? color.r : color.g;
                    minComponent = color.b < minComponent ? color.b : minComponent;
                    float sat = maxComponent - minComponent;
                    if (sat < 0)
                    {
                        sat = 0;
                    }
                    else if (sat > 1f)
                    {
                        sat = 1f;
                    }
                    float luma = color.GetLuma();
                    color.r *= 1f + vibrance * (1f - sat) * (color.r - luma);
                    color.g *= 1f + vibrance * (1f - sat) * (color.g - luma);
                    color.b *= 1f + vibrance * (1f - sat) * (color.b - luma);
                }
                // tinting
                float tintAmount = colorAdjustments.tintAmount;
                if (tintAmount > 0)
                {
                    Color tintedColor = new Color(color.r * colorAdjustments.tintColor.r, color.g * colorAdjustments.tintColor.g, color.b * colorAdjustments.tintColor.b);
                    color = Color.Lerp(color, tintedColor, tintAmount);
                }
                // contrast
                float contrast = colorAdjustments.contrast + 1f;
                if (contrast != 1f)
                {
                    color.r = (color.r - 0.5f) * contrast + 0.5f;
                    color.g = (color.g - 0.5f) * contrast + 0.5f;
                    color.b = (color.b - 0.5f) * contrast + 0.5f;
                }
                // brightness
                float brightness = colorAdjustments.brightness + 1f;
                if (brightness != 1f)
                {
                    color.r *= brightness;
                    color.g *= brightness;
                    color.b *= brightness;
                }
            }

            return(color);
        }
예제 #2
0
        Color GetTransformedColor(Color originalColor)
        {
            switch (currentBrush)
            {
            case Brush.Darken: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l -= 0.05f;
                if (hsl.l < 0.01f)
                {
                    hsl.l = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Lighten: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l += 0.05f;
                if (hsl.l > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Dry: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.s -= 0.05f;
                if (hsl.s < 0.01f)
                {
                    hsl.s = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Vivid: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.s += 0.05f;
                if (hsl.s > 0.99f)
                {
                    hsl.s = 0.99f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Noise: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l += Random.value * 0.1f - 0.05f;
                if (hsl.l > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                else if (hsl.l < 0.01f)
                {
                    hsl.l = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.NoiseTone: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.h += Random.value * 0.1f - 0.05f;
                if (hsl.h > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                else if (hsl.h < 0.01f)
                {
                    hsl.h = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Gradient: {
                HSLColor hsl      = ColorConversion.GetHSLFromRGB(_brushColor.r, _brushColor.g, _brushColor.b);
                int      distance = Mathf.Max(Mathf.Abs(startTexelPos.x - currentTexelPos.x), Mathf.Abs(startTexelPos.y - currentTexelPos.y));
                if (distance > 0)
                {
                    hsl.l -= 0.05f * distance;
                    if (hsl.l < 0.01f)
                    {
                        hsl.l = 0.01f;
                    }
                    return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
                }
                return(_brushColor);
            }
            }
            return(_brushColor);
        }