Создание класса GrayScaleBrushes - PullRequest
10 голосов
/ 10 января 2011

Недавно я наткнулся на диаграмму цвета .NET, основанную на их значении оттенка и яркости. Меня поразила сумасшедшая диаграмма в градациях серого. Например, DarkGray на самом деле светлее серого? Кроме того, я не вижу никакой логики в градации значений RGB, она идет от 0 до 105 до 128?

0   : Black
105 : DimGray 
128 : Gray
169 : DarkGray!
192 : Silver
211 : LightGray 
220 : Gainsboro
245 : Ghostwhite
255 : White

http://sites.google.com/site/cdeveloperresources/

color chart - see link above

Мне нужен класс GrayScaleBrushes, который ведет себя точно так же, как класс Brushes, но с моей собственной схемой, например:

GrayScaleBrushes.Pct05
GrayScaleBrushes.Pct10
GrayScaleBrushes.Pct15
..all the way to.Pct95
...
ie: e.FillRectangle( GrayScaleBrushes.Pct05, exampleRect );

Как это сделать, убедившись, что щетки будут располагаться правильно?

Редактировать: Класс .NET Brushes выглядит следующим образом (разобран с помощью рефлектора).

public sealed class Brushes
{
    // Fields
    private static readonly object AliceBlueKey = new object();

    // Methods
    private Brushes()
    {
    }

    // Properties
    public static Brush AliceBlue
    {
        get
        {
            Brush brush = (Brush) SafeNativeMethods.Gdip.ThreadData[AliceBlueKey];
            if (brush == null)
            {
                brush = new SolidBrush(Color.AliceBlue);
                SafeNativeMethods.Gdip.ThreadData[AliceBlueKey] = brush;
            }
            return brush;
        }
    }
}

SafeNativeMethods мне кажется недоступным. Предположим, я только что возвратил SolidBrush в статическом методе, это заставило бы все располагаться правильно? (А как это проверить?)

public sealed class GrayScaleBrushes
{
    private static SolidBrush pct05 = null;

    public static SolidBrush Pct05
    {
        get
        {
            if (pct05 == null)
            {
                int rgbVal = GetRgbValFromPct( 5 );
                pct05 = new SolidBrush(Color.FromArgb(rgbVal, rgbVal, rgbVal));
            }
            return pct05;
        }
    }

    private static int GetRgbValFromPct(int pct)
    {
        return 255 - (int)(((float)pct / 100f) * 255f);
    }
}

Ответы [ 3 ]

1 голос
/ 19 апреля 2011

В этом случае SafeNativeMethods - это простой кэш, содержащий копию кисти. Таким образом, повторный вызов свойства get не создаст новый экземпляр. Вместо этого он всегда будет возвращать одну и ту же кисть.

Для этого вы можете переписать свою функцию, например, так:

public static class GrayScaleBrushes
{
    private static SolidBrush _Pct05;

    public static SolidBrush Pct05
    {
        get
        {
            if (_Pct05 == null)
            {
                var value = GetRgbValFromPct(5);
                _Pct05 = new SolidBrush(Color.FromArgb(value, value, value));
            }

            return _Pct05;
        }
    }

    private static int GetRgbValFromPct(int pct)
    {
        // no need to convert to float and back to int again
        return 255 - ((pct * 255) / 100);
    }
}

Это решение будет создавать серые шкалы по мере необходимости, но за счет затрат на проверку null при каждом вызове. Вы можете решить эту проблему со скоростью , изменив ее снова на проблему с памятью , применив такой подход:

public static class GrayScaleBrushes
{
    public static readonly SolidBrush Pct05;

    static GrayScaleBrushes()
    {
        var value = GetRgbValFromPct(5);
        Pct05 = new SolidBrush(Color.FromArgb(value, value, value));
    }
}

Но я думаю, что в этом случае это просто вопрос вкуса, потому что ни скорость, ни память не будут настоящей проблемой в обоих случаях.

1 голос
/ 24 апреля 2011

Я бы порекомендовал следующее:

Создать статический класс GrayScaleBrushes

Создать статический словарь с процентом интенсивности (int) в качестве ключа,

Создатьодиночное статическое индексированное свойство 'Pct', которое вы будете использовать, например, GrayScaleBrushes.Pct [10], которое будет возвращать словарную запись.

Теперь вы можете делать то, что сказал Оливер, и создавать записи словаря на лету, как они 'Вызван, или вы можете использовать статический конструктор для циклического перебора 20 записей и добавления их в словарь.

Этот метод избавит вас от необходимости создавать и поддерживать 20 нечетных свойств.Приветствия.

1 голос
/ 11 января 2011

Класс Brushes является статическим и может пропускать только небольшое количество ресурсов, соответствующее количеству определенных цветов, поэтому просто разрешите очистить эти ресурсы при выходе из приложения. Вместо этого убедитесь, что ваши кисти на самом деле не созданы, если на них нет ссылок. Это ускорит запуск и гарантирует, что неиспользуемые цвета не потребляют ресурсы.

...