c# - 构建 GrayScaleBrushes 类

标签 c# .net gdi+

最近我发现了一个基于色调和亮度值的 .NET 颜色图表。让我印象深刻的是疯狂的灰度图。例如,DarkGray 实际上比 Gray 更亮?另外,我在 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);
    }
}

最佳答案

在这种情况下,SafeNativeMethods 只是一个保存画笔副本的简单缓存。因此,对属性 getter 的第二次调用不会创建新实例。相反,它将始终返回相同的画笔。

要实现这一点,您可以像这样重写您的函数:

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

但我认为在这种情况下,这只是一个品味问题,因为在这两种情况下,速度和内存都不是真正的问题。

关于c# - 构建 GrayScaleBrushes 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4650626/

相关文章:

c# - 从位图数组创建大位图的快速方法?

winforms - 如何避免 Graphics.MeasureString() 中出现错误的零宽度连接器异常?

c# - 帮助制作一个好的正则表达式?

c# - 在 MVC 4 中为 3 层架构配置 Ninject

C# EWS 托管 API : How to access shared mailboxes but not my own inbox

c# - VB.NET : What is static T (C#) in VB. 网络?

c++ - Gdiplus::Bitmap::FromHICON 失败

c# - 如何只搜索 XDocument 的子项,而不是其所有后代?

.net - 从 LINQ to SQL 迁移时需要注意的事项 --> LINQ to Entities

c# - 如何将 X509SigningCredentials 与 System.IdentityModel.Tokens.Jwt.JwtHeader 一起使用?