Как добавить два класса кистей

Есть ли способ или обходной путь для объединения/добавления двух классов System.Drawing.Brush вместе?

e.g. Brush b1 = GetFromSomewhere();

Brush b2 = GetFromSomewhereElse();

(что-то подобное...)

Brush b3 = b1 + b2; 

В конце концов, моя цель - сделать что-то вроде:

Graphics graphics = new Graphics; 
graphics.FillRectangle(b3, rectangle);

Обновление: у меня есть сторонняя библиотека (не могу ее контролировать), которая дает мне предопределенный экземпляр кисти (представляет шаблон заливки, например ++++ или #####). Я хочу «наложить» этот экземпляр на свой «собственный» рисунок кисти.


person Community    schedule 02.10.2014    source источник
comment
Как это должно выглядеть?   -  person Lucas Trzesniewski    schedule 02.10.2014
comment
В настоящее время нет ничего, что можно было бы объединить или добавить две кисти. Вам нужно будет определить, что это значит, прежде чем кто-то сможет предложить обходной путь.   -  person Peter Ritchie    schedule 02.10.2014
comment
Если вы хотите смешать цвета, это будет легко. Мы говорим о SolidBrush здесь? Есть и другие, гораздо более сложные типы кистей, в которых смешивание не имеет особого смысла. Или, может быть, вы имеете в виду КомпаундПен?   -  person TaW    schedule 02.10.2014
comment
Почему минус, пожалуйста? Это прекрасно объясненный вопрос   -  person    schedule 03.10.2014
comment
Не мои отрицательные голоса, но: - Сейчас, но вы не торопились, разъясняя, что вам нужно. Противники не возвращаются, чтобы проверить дела, у них действительно мало времени, так много постов, так много, чтобы проголосовать против .. ;-)   -  person TaW    schedule 03.10.2014


Ответы (1)


Обновление:

Поскольку вы, наконец, уточнили, чего хотите, вот решение для смешивания двух TextureBrushes:

Я предполагаю, что у вас есть шаблон для вашего TextureBrush в файле Image img2. Используйте простой метод ниже, чтобы смешать два изображения одинакового размера и создать новую кисть, используя объединенные шаблоны:

TextureBrush brush3 = new TextureBrush(
                      mixBitmaps( (Bitmap)(brush1.Image), (Bitmap) img2)  );

Теперь вы можете рисовать или заполнять что-то с ним.

Bitmap mixBitmaps(Bitmap bmp1, Bitmap bmp2)
{
    using (Graphics G = Graphics.FromImage(bmp1) )
    {
        G.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
        G.DrawImage(bmp2, Point.Empty);
    }
    return bmp1;
}

Вот пример:

смесь текстур


Я оставляю старый ответ, так как некоторые люди тоже интересовались им:

Если вы хотите смешать цвета, вы можете сделать это легко, например, так:

SolidBrush MixColor(SolidBrush b1, SolidBrush b2)
{
    return new SolidBrush(Color.FromArgb(Math.Max(b1.Color.A, b2.Color.A),
                         (b1.Color.R + b2.Color.R) / 2, (b1.Color.G + b2.Color.G) / 2,
                         (b1.Color.B + b2.Color.B) / 2));
}

Вместо этого вы можете установить для альфа-канала фиксированное значение 255.

Однако это упрощенное среднее вычисление, которое не будет работать, если цвета не близки.

Для лучшего смешивания вы должны смешивать оттенки отдельно от значений насыщенности и яркости, то есть вам придется конвертировать в HSL или HSV, смешивать там и конвертировать обратно в RGB.

Вот версия, которая должна делать именно это:

SolidBrush MixBrushes(SolidBrush br1, SolidBrush br2)
{   
    return new SolidBrush ( MixColorHSV( br1.Color, br2.Color) );
} 

Color MixColorHSV(Color c1 , Color c2 )
{
    double h1 = c1.GetHue();
    double h2 = c2.GetHue();
    double d = (h2 - h1) / 2d;
    double h = h1 + d;
    if (d > 90) h -= 180;  else if (d < -90) h += 180;  // correction 1!
    if (h < 0) h += 360; else if (h > 360) h -= 360;    // correction 2!

    int max1 = Math.Max(c1.R, Math.Max(c1.G, c1.B));
    int min1 = Math.Min(c1.R, Math.Min(c1.G, c1.B));
    double s1 = (max1 == 0) ? 0 : 1d - (1d * min1 / max1);
    double v1 = max1 / 255d;

    int max2 = Math.Max(c2.R, Math.Max(c2.G, c2.B));
    int min2 = Math.Min(c2.R, Math.Min(c2.G, c2.B));
    double s2 = (max2 == 0) ? 0 : 1d - (1d * min2 / max2);
    double v2 = max2 / 255d;

    double s = (s1 + s2) / 2d;
    double v = (v1 + v2) / 2d;

    return ColorFromHSV(h,s,v);
}

public static Color ColorFromHSV(double hue, double saturation, double value)
{
    int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
    double f = hue / 60 - Math.Floor(hue / 60);

    value = value * 255;
    int v = Convert.ToInt32(value);
    int p = Convert.ToInt32(value * (1 - saturation));
    int q = Convert.ToInt32(value * (1 - f * saturation));
    int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));

    if (hi == 0)       return Color.FromArgb(255, v, t, p);
    else if (hi == 1)  return Color.FromArgb(255, q, v, p);
    else if (hi == 2)  return Color.FromArgb(255, p, v, t);
    else if (hi == 3)  return Color.FromArgb(255, p, q, v);
    else if (hi == 4)  return Color.FromArgb(255, t, p, v);
    else               return Color.FromArgb(255, v, p, q);
}

См. этот пост для части преобразования!

Вот диаграмма цветов, в которой сравниваются две смеси с добавлением красного с цветами, расположенными на 30° дальше друг от друга. Обратите внимание, сколько простых миксов темнее с меньшей насыщенностью: два цветовых микса

person Community    schedule 02.10.2014
comment
Вот и все! Отлично спасибо - person ; 03.10.2014