1

这两个表达式是否应该产生大致相同的颜色?

Color.FromArgb(255, 255, 255, (byte)0.25 * 255))

Color.FromScRgb(1.0f, 1.0f, 1.0f, 0.25f))

这个测试程序展示了它们以看似不同的 alpha 值显示:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Test_FromArgb_FromScRbg
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var panel = new StackPanel();

            Content = panel;

            panel.Children.Add(
                new Rectangle()
                {
                    Width = 100,
                    Height = 100,
                    Fill = new SolidColorBrush(
                        Color.FromArgb(
                            255, 
                            255, 
                            255, 
                            (byte)0.25 * 255))
                });

            panel.Children.Add(
                new Rectangle()
                {
                    Width = 100,
                    Height = 100,
                    Fill = new SolidColorBrush(
                        Color.FromScRgb(
                            1.0f,
                            1.0f,
                            1.0f,
                            0.25f))
                });
        }
    }
}

这是演示程序在我的系统上的样子:

在此处输入图像描述

4

4 回答 4

2

上面mzzzzb提到了这背后的基本原因:

比例 0.0 - 1.0 不会线性映射到 0 - 255

即,ScRgb 组件不会线性映射到 Argb 组件。

于 2012-11-25T19:58:58.357 回答
1

从文档中我可以看到最后一个参数实际上是您正在修改的蓝色组件,alpha 是相同的;两种颜色完全不透明

(byte) 0.25 * 255在乘法之前会给你0蓝色,所以第一个实际上是纯黄色。你应该这样做0.25byteRGB(255, 255, 0)(byte) (0.25 * 255)RGB(255, 255, 63)

当我用第二种颜色画画时,我发现它实际上是RGB(255, 255, 140)。所以看起来比例 0.0 - 1.0 并没有线性映射到 0 - 255。

于 2012-10-27T04:25:55.823 回答
0

尝试使用ColorFloatToByte方法来获得您想要的结果:

private static byte ColorFloatToByte(float val)
{
    if (!(val > 0.0)) // Handles NaN case too
        return (0);
    else if (val <= 0.0031308)
        return ((byte)((255.0f * val * 12.92f) + 0.5f));
    else if (val < 1.0)
        return ((byte)((255.0f * ((1.055f * 
               (float)Math.Pow((double)val, (1.0 / 2.4))) - 0.055f)) + 0.5f));
    else
        return (255);
}

用法:

Color.FromArgb(255, 255, 255, ColorFloatToByte(0.25f)))

Color.FromScRgb(1.0f, 1.0f, 1.0f, 0.25f))
于 2012-10-27T03:45:56.140 回答
0

与已经提到的答案相同 - 它们不是线性映射(它们是不同的颜色空间 - ScRGB 不是更高精度的 SRGB)

对于 mzzzzb “@FurqanSafdar,您给出的解决方案可能是正确的。但这不是重点,问题是 - 直觉上我们假设它们是线性相关的。顺便说一句,您是如何获得该解决方案的”

(我们都知道假设的作用。)也许链接到 sRGB 和 ScRGB 的定义会更好!另外,鉴于它们是具有不同范围的不同色彩空间,您为什么要假设?

您可以看到源代码以及正在执行的操作:

FromScRGB

来自Argb

特别是转换功能:

ScRgbTosRgb

sRgbToScRgb

ScRgbTosRgb 函数就是 Furqan Safdar 提到的 ColorFloatToByte。

于 2020-11-17T18:33:14.740 回答