构建 GrayScaleBrushes 类

发布于 2024-10-11 00:30:30 字数 2027 浏览 8 评论 0原文

最近我发现了一个基于色调和亮度值的 .NET 颜色图表。最让我感动的是那疯狂的灰度图。例如,深灰色实际上比灰色更浅?另外,我看不到 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/

颜色图表 - 请参阅上面的链接

我想要的是一个 GrayScaleBrushes 类,其行为与 Brushes 类完全相同,但具有我的自定义方案,例如:

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

如何这样做,确保刷子能够正确处理?

编辑: .NET Brushes 类如下所示(使用 Reflector 进行反汇编)。

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

Recently I came across a .NET color chart based on their hue and brightness value. What stroke me is the crazy grayscale chart. For example, DarkGray is actually lighter then Gray ? Also, I can't see any logic in the gradation of rgb values, it goes from 0 to 105 to 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

What I want is a GrayScaleBrushes class which behaves exactly like the Brushes class, but with my custom scheme, like :

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

How to do that, making sure that the brushes will dispose correctly ?

Edit: The .NET Brushes class looks like the following (disassembled using reflector ).

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 seems unaccessible to me. Suppose I just returned a SolidBrush in a static method, would that make everything dispose correctly ? (And how to test that?)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

说好的呢 2024-10-18 00:30:30

在本例中,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));
    }
}

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

The SafeNativeMethods is in this case just a simple cache that holds a copy of the brush. So a second call to the property getter won't create a new instance. Instead it will always return the same brush.

To accomplish this you could rewrite your function maybe like this:

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

This solution will create the gray scales as needed but by the costs of checking for the null every time it is called. You can accomplish this speed problem by changing it again a memory problem by taking an approach like this:

public static class GrayScaleBrushes
{
    public static readonly SolidBrush Pct05;

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

But i think in this case it just a matter of taste, cause nor the speed nor the memory will be a real problem in both cases.

甜宝宝 2024-10-18 00:30:30

Brushes 类是静态的,只能泄漏与定义的颜色数量相对应的少量资源,因此只需在应用程序退出时清理这些资源即可。相反,请确保您的画笔不会被实际创建,除非它们被引用。这将加快启动速度并确保未使用的颜色不会消耗资源。

The Brushes class is static can only leak a small number of resources corresponding to the number of colors defined so just let those resources be cleaned up upon application exit. Instead concern yourself with ensuring that your brushes are not actually created unless they are referenced. That will speed up startup and ensure that unused colors don't consume resources.

街角卖回忆 2024-10-18 00:30:30

我建议以下操作:

创建一个静态类 GrayScaleBrushes

创建一个以强度百分比 (int) 作为键的静态字典,

创建一个您将使用的静态索引属性“Pct”,如 GrayScaleBrushes.Pct[10] 它将返回字典条目。

现在,您可以按照 Oliver 所说的那样,在调用时动态创建字典条目,也可以使用静态构造函数循环遍历 20 个条目并将它们添加到字典中。

此方法将使您不必创建和维护这 20 个奇怪的属性。干杯。

I would recommend the following:

Create a static class GrayScaleBrushes

Create a static Dictionary of with the intensity percentage (int) as the key,

Create a single static Indexed Property 'Pct' that you would use like GrayScaleBrushes.Pct[10] which would return the dictionary entry.

Now you could either do as Oliver said and create the dictionary entries on the fly as they're called, or you could use a static constructor to loop through the 20 entries and add them to the dictionary.

This method woud save you from having to create and maintain the 20 odd properties. Cheers.

來不及說愛妳 2024-10-18 00:30:30

我使用上面提到的颜色图表很多年了,现在所有者突然删除了这个谷歌网站。离开这里,追寻历史。

输入图片此处描述

I used above mentioned color chart for years and now owner suddenly delete this Google site. Leave here for a history.

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文