这是绘制椭圆的示例代码,启用了阴影。我将填充和阴影颜色设置为相同。但在视图中阴影颜色是不同的。这可能是WPF功能,但在我的场景中,我想为对象设置所需的阴影颜色。
<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>
答案 0 :(得分:2)
看起来DropShadowEffect在呈现自身时会以某种方式影响Color。这个问题似乎不存在于原色(所谓的颜色,如Red,Blue,Aqua等 - 但你不必使用名称,你也可以通过#AARRGGBB格式指定它们。)< / p>
我无法弄清楚它的确切修改,也无法提供解决方法(除了使用命名颜色......),但我想也许值得在答案中注明。
请参阅其他问题,这些问题可能指向DropShadowEffect的相同“bug”或未记录的功能:
更新: 所以,这是作弊,但对于您的具体问题,它可能会解决问题:
<Grid>
<Canvas>
<Ellipse Width="200" Height="300" Fill="#7D00FE">
<Ellipse.Effect>
<DropShadowEffect
ShadowDepth="5"
Color="#BA00FE"/>
</Ellipse.Effect>
</Ellipse>
</Canvas>
</Grid>
通过一些投入工作,人们可以想出一个转换器,它可以将颜色转换为另一种颜色,这将是给定颜色所需的DropShadowEffect颜色。如果我有一点时间,我会回到这里。
我的直觉表明问题可能出在特定效果的着色器代码中,并且输出可能在不同的硬件(和/或驱动程序版本)上有所不同,但目前我无法证明这一点。
<强>更新强>
我对命名颜色错了,它并不适用于所有这些颜色,例如:绿色是有缺陷的,但问题不在于 - 仅仅 - 取决于颜色的绿色成分。有趣的。
更新2:
所以这是我之前谈过的转换器:
using System;
using System.Windows.Data;
using System.Windows.Media;
namespace MyCustomConverters
{
public class ColorToShadowColorConverter: IValueConverter
{
#region IValueConverter Members
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;
var r = Transform(color.R);
var g = Transform(color.G);
var b = Transform(color.B);
// return with Color and not SolidColorBrush, otherwise it will not work
// This means that most likely the Color -> SolidBrushColor conversion does the RBG -> sRBG conversion somewhere...
return Color.FromArgb(color.A, r, g, b);
}
return value;
}
private byte Transform(byte source)
{
// see http://en.wikipedia.org/wiki/SRGB
return (byte)(Math.Pow(source / 255d, 1 / 2.2d) * 255);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("ColorToShadowColorConverter is a OneWay converter.");
}
#endregion
}
}
这是应该如何使用的:
资源部分:
<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的回答,因为它引导我朝着正确的方向前进。
答案 1 :(得分:2)
它正在将DropShadowEffect转换为特定的Sc值。
你越接近1,差异越小(因此FF / 255/1工作得非常好),因为n的第1个根是1
通过研究和研究ScRGB,ScRGB的伽玛值约为2.2。因此,当从RGB转换为ScRGB时,您可能需要除以255,然后除以值的第n(2.2)个根来得出最终值。
E.g。
value 5E is 94
94 / 255 = 0.36862745098039215686274509803922
2.2root of 94/255 = 0.635322735100355
0.635322735100355 * 255 = ~162 = A2
因此,当您将前景的绿色设置为5E时,需要将DropShadowEffect设置为A2。
这只是我的观察以及我从研究中得出的结论。
为什么MS会像这样实现它?我没有想法
来源:
因此,在您的示例中,您需要使用相同的颜色#B800FE
答案 2 :(得分:2)
如Ciechan's answer中所述(感谢Ciechan先生),Microsoft将DropShadowEffect转换为特定的Sc值。
那么如何解决呢?
让微软通过在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
有关绑定转换器的技术详情,请参阅@qqbenq's answer中的更新2 (感谢@qqbenq)。
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;
}
答案 3 :(得分:0)
这是针对@qqbenq 's answer改进的公式。
更改位于Transform功能中。它更精确,差异大约为1。 因此,在提问者示例中,您需要使用相同的颜色#BA00FF,您将获得#7D00FF(为#7D00FE请求提问者)。
https://www.nayuki.io/page/srgb-transform-library
中找到的公式的参考来源 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);
}