How to append two brush classes [closed]

落爺英雄遲暮 提交于 2019-12-12 09:26:58

问题


Is there any way or workaround to combine/append two System.Drawing.Brush classes together?

e.g. Brush b1 = GetFromSomewhere();

Brush b2 = GetFromSomewhereElse();

(something like that...)

Brush b3 = b1 + b2; 

Eventually my purpose is to do something like:

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

Update: I have a third party library (have no control over it) which gives me a predefined Brush instance (represents a fill pattern, e.g. ++++ or #####). I want to "overlay" that instance with my "own" brush pattern.


回答1:


Update:

Since you have finally clarified what you want here is a solution to mix two TextureBrushes:

I assume you have the pattern for your TextureBrush in the Image img2. Use the simple method below to mix two images of the same size and create the new brush by using the combined patterns:

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

Now you can paint or fill stuff with it..

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;
}

Here is an example:


I leave the old answer, since some folks were interested in it, too:

If you want to mix the Colors you can do it easily, maybe like this:

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));
}

You may want to set the alpha channel to a fixed value of 255 instead.

However this is a simplistic average caculation, which will not work well if the colors are not close.

For a better mix you would mix the hues separatly from the saturation and the brightness values, that is you would have to convert to HSL or HSV, mix there and convert back to RGB..

Here is a version that should do just that:

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);
}

See this post for parts of the conversion!

Here is a color chart that compares the two mixes adding Red with colors each 30° farther away. Note how many of the simple mixes are murkier with less saturation:



来源:https://stackoverflow.com/questions/26165071/how-to-append-two-brush-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!