WPF如何为阴影设置所需的颜色?
这是绘制椭圆的示例代码,启用了阴影。我将填充和阴影颜色设置为相同。但在视图中阴影的颜色是不同的。这可能是WPF功能,但在我的场景中,我想为对象设置所需的阴影颜色WPF如何为阴影设置所需的颜色?,wpf,Wpf,这是绘制椭圆的示例代码,启用了阴影。我将填充和阴影颜色设置为相同。但在视图中阴影的颜色是不同的。这可能是WPF功能,但在我的场景中,我想为对象设置所需的阴影颜色 <Window x:Class="Test.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml
<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Canvas>
<Ellipse Width="200" Height="300" Fill="#7D00FE">
<Ellipse.Effect>
<DropShadowEffect
ShadowDepth="5"
Color="#7D00FE"/>
</Ellipse.Effect>
</Ellipse>
</Canvas>
</Grid>
</Window>
看起来DropShadowEffect在渲染自身时会以某种方式影响颜色。对于原色(即所谓的颜色,如红色、蓝色、浅绿色等),似乎不存在此问题。但您不必使用名称,也可以通过#AARGGBB格式指定它们。) 我无法弄清楚它到底做了什么修改,也无法提供解决方案(除了使用命名颜色…),但我想也许值得在回答中注意一下 请参阅其他问题,这些问题可能指向DropShadowEffect的相同“bug”或未记录的功能:
<Grid>
<Canvas>
<Ellipse Width="200" Height="300" Fill="#7D00FE">
<Ellipse.Effect>
<DropShadowEffect
ShadowDepth="5"
Color="#BA00FE"/>
</Ellipse.Effect>
</Ellipse>
</Canvas>
</Grid>
下面是应该如何使用它:
资源部分:
<namespaceDefinedByXmlnsProperty:ColorToShadowColorConverter x:Key="ColorConverter" />
实际用途:
<Ellipse Width="50" Height="100" Fill="#7D00FE">
<Ellipse.Effect>
<DropShadowEffect ShadowDepth="50"
Color="{Binding Fill, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType={x:Type Ellipse}},
Converter={StaticResource ColorConverter}}"/>
</Ellipse.Effect>
</Ellipse>
感谢Michal Ciechan的回答,因为它指引了我正确的方向。在某个地方,它正在将DropShadow效果转换为特定的Sc值 越接近1,差异就越小(因此FF/255/1工作得非常好),因为1的第n个根是1 通过对这一点的研究和对ScRGB的研究,ScRGB的伽马值约为2.2。因此,当从RGB转换为ScRGB时,您可能需要除以255,然后再除以该值的第n(2.2)个根以得出最终值 例如 因此,当您将前景的绿色设置为5E时,需要将DropShadowEffect设置为A2 这只是我的观察和我的研究得出的结论 微软为什么要这样实施它?我不知道 资料来源:
因此,在您的示例中,要获得相同的颜色,您需要使用#B800FE这里有一个改进的公式 这些变化发生在变换函数中。它更精确,差值约为1。 因此,在提问者示例中,要使用相同的颜色,您需要使用#BA00FF,您将获得#7D00FF(提问者要求使用#7D00FE) 中找到的公式的参考源
专用字节转换(字节源)
{
//看http://en.wikipedia.org/wiki/SRGB
返回(字节)(数学功率(源/255d,1/2.2d)*255);
双x=(双)源/255;
如果(x=1)
返回1;
否则如果(x<0.0031308f)
返回(字节)(x*12.92f*255);
其他的
返回(字节)((数学功率(x,1/2.4)*1.055-0.055)*255);
}
如中所述(感谢Ciechan先生),Microsoft将DropShadowEffect转换为特定的Sc值
那么如何解决呢
只需让Microsoft通过在sRGB中输入RGB值来进行计算
//Where the variable color is the expected color.
Color newColor = new Color();
newColor.ScR = color.R;
newColor.ScG = color.G;
newColor.ScB = color.B;
//the converted color value is in newColor.R, newColor.G, newColor.B
有关绑定转换器的技术详细信息,请参阅中的更新2
这似乎是DropShadowEffect中的一个问题:
value 5E is 94
94 / 255 = 0.36862745098039215686274509803922
2.2root of 94/255 = 0.635322735100355
0.635322735100355 * 255 = ~162 = A2
private byte Transform(byte source)
{
// see http://en.wikipedia.org/wiki/SRGB
return (byte)(Math.Pow(source / 255d, 1 / 2.2d) * 255);
double x = (double)source / 255;
if (x <= 0)
return 0;
else if (x >= 1)
return 1;
else if (x < 0.0031308f)
return (byte)(x * 12.92f * 255);
else
return (byte)((Math.Pow(x, 1 / 2.4) * 1.055 - 0.055) * 255);
}
//Where the variable color is the expected color.
Color newColor = new Color();
newColor.ScR = color.R;
newColor.ScG = color.G;
newColor.ScB = color.B;
//the converted color value is in newColor.R, newColor.G, newColor.B
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Only touch the shadow color if it's a solid color, do not mess up other fancy effects
if (value is SolidColorBrush)
{
Color color = ((SolidColorBrush)value).Color;
//Where the variable color is the expected color.
Color newColor = new Color();
newColor.ScR = (float)color.R / 255;
newColor.ScG = (float)color.G / 255;
newColor.ScB = (float)color.B / 255;
return newColor;
}
return value;
}