M Rest
M Rest

Reputation: 63

I want to get various shades of a color - can this be done in UWP?

In my app I want to show a variety of shades of a user defined color. I cannot find UWP methods to do that. Is it possible? I'm programming in C#.

Upvotes: 0

Views: 504

Answers (3)

Martin Tirion
Martin Tirion

Reputation: 1236

This is not standard supported in the UWP platform, but it's easy to do just using math ;) I've created a helper class to do just that. There is also an extra class for defining the HSV structure. The trick is to get the Hue, Saturation and Brightness (or Value) of the color and then modify the Brightness (Value).

In the class below, call the GetColors method to get a list of shades for that color.

public class ColorHelper
{
    public static List<Windows.UI.Color> GetColors(Windows.UI.Color baseColor, int max)
    {
        // fill color shades list
        List<Windows.UI.Color> colorShades = new List<Windows.UI.Color>();
        HSVColor hsv = ColorHelper.RGBtoHSV(baseColor);
        hsv.V = 255; // alway use highest brightness to determine collection of shades
        double v = hsv.V / max;
        for (int i = 0; i < max; i++)
        {
            hsv.V = v * i;
            if (hsv.V > 255) hsv.V = 255;
            colorShades.Add(ColorHelper.HSVtoRGB(hsv));
        }
        return colorShades;
    }

    public static HSVColor RGBtoHSV(Windows.UI.Color rgb)
    {
        double max, min, chroma;
        HSVColor hsv = new HSVColor();

        min = Math.Min(Math.Min(rgb.R, rgb.G), rgb.B);
        max = Math.Max(Math.Max(rgb.R, rgb.G), rgb.B);
        chroma = max - min;

        if (chroma != 0)
        {
            if (rgb.R == max)
            {
                hsv.H = (rgb.G - rgb.B) / chroma;
                if (hsv.H < 0.0) hsv.H += 6.0;
            }
            else if (rgb.G == max)
            {
                hsv.H = ((rgb.B - rgb.R) / chroma) + 2.0;
            }
            else
            {
                hsv.H = ((rgb.R - rgb.G) / chroma) + 4.0;
            }
            hsv.H *= 60.0;
            hsv.S = chroma / max;
        }

        hsv.V = max;
        hsv.A = rgb.A;

        return hsv;
    }

    public static Windows.UI.Color HSVtoRGB(HSVColor hsv)
    {
        double min, chroma, hdash, x;
        Windows.UI.Color rgb = new Windows.UI.Color();

        chroma = hsv.S * hsv.V;
        hdash = hsv.H / 60.0;
        x = chroma * (1.0 - Math.Abs((hdash % 2.0) - 1.0));

        if (hdash < 1.0)
        {
            rgb.R = (byte)chroma;
            rgb.G = (byte)x;
        }
        else if (hdash < 2.0)
        {
            rgb.R = (byte)x;
            rgb.G = (byte)chroma;
        }
        else if (hdash < 3.0)
        {
            rgb.G = (byte)chroma;
            rgb.B = (byte)x;
        }
        else if (hdash < 4.0)
        {
            rgb.G = (byte)x;
            rgb.B = (byte)chroma;
        }
        else if (hdash < 5.0)
        {
            rgb.R = (byte)x;
            rgb.B = (byte)chroma;
        }
        else if (hdash < 6.0)
        {
            rgb.R = (byte)chroma;
            rgb.B = (byte)x;
        }

        min = hsv.V - chroma;

        rgb.R += (byte)min;
        rgb.G += (byte)min;
        rgb.B += (byte)min;
        rgb.A = (byte)hsv.A;

        return rgb;
    }
}

public class HSVColor
{
    public double H { get; set; }
    public double S { get; set; }
    public double V { get; set; }
    public double A { get; set; }

    public HSVColor()
    {
        H = S = V = A = 1.0;
    }
}

Upvotes: 1

Joel
Joel

Reputation: 2361

You can use a LinearGradientBrush or a RadialGradientBrush. You should only need to add two GradientStops to show a range. Set the background of some element to be painted with the gradient brush.

<Page
x:Class="CarServiceLogger.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CarServiceLogger"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!--{ThemeResource ApplicationPageBackgroundThemeBrush}-->
<Grid >
    <Grid.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
            <GradientStop Offset="0" Color="#FF0000"   />
            <GradientStop Offset="1" Color="#000000" />
        </LinearGradientBrush>
    </Grid.Background>

</Grid>
</Page>

Upvotes: 0

Yuriy Pelekh
Yuriy Pelekh

Reputation: 308

It is a tricky question about shades. Shade should be at least from one color to another. The simplest shade is from selected color to black. You can implement it as changing alpha-channel (transparancy) from 255 to 0 with black color below (background). See shades of blue: https://en.wikipedia.org/wiki/Tints_and_shades#/media/File:Kleurenovergang_van_zwart_naar_blauw.png

Upvotes: 0

Related Questions