2011-01-10 38 views
9

最近我遇到了一个基于色调和亮度值的.NET颜色图表。什么让我感到疯狂的灰度图。例如,DarkGray实际上比Gray更轻?另外,我看不到rgb值渐变中的任何逻辑,它从0到105到128?建立一个GrayScaleBrushes类

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笔刷类如下所示(使用反射器反汇编)。

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

至于原因`深灰> Gray`,请参见维基百科:http://en.wikipedia.org/wiki/X11_color_names#Color_names_that_clash_between_X11_and_HTML.2FCSS – 2011-01-10 20:52:13

回答

1

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

但我认为在这种情况下,它只是味道,原因也不是速度,也不是一个问题记忆在两种情况下都是一个真正的问题。

1

Brushes类是静态的,只能泄漏少量对应的定义所以才让这些资源应用程序退出时被清理的颜色数量的资源。相反,请务必确保您的画笔除非被引用,否则不会实际创建。这将加速启动并确保未使用的颜色不会消耗资源。

1

我想提出以下建议:

创建一个静态类GrayScaleBrushes

创建与强度百分比(INT)为核心的静态字典,

创建一个单一的静态索引属性“ Pct',你会像GrayScaleBrushes.Pct [10]那样使用它来返回字典条目。

现在你既可以做奥利弗说和动态创建字典条目,他们是所谓的,或者你可以通过20项使用静态构造函数循环,并将其添加到字典中。

这种方法woud不必创建和维护20个多属性救你。干杯。