【问题标题】:C# WriteableBitmapEx Pixels Premultiplying Bit-shiftingC# WriteableBitmapEx 像素预乘位移
【发布时间】:2010-12-16 12:45:44
【问题描述】:

这是关于从像素值中提取 RGB。这是代码sn-p:

        Byte a = (Byte)(myColor >> 24);
        // Prevent division by zero
        UInt32 ai = a;
        if (ai == 0)
        {
            ai = 1;
        }
        ai = ((255 << 8) / ai);
        Byte bA = a;
        Byte bR = (Byte)((((myColor >> 16) & 0xFF) * ai) >> 8);
        Byte bG = (Byte)((((myColor >> 8) & 0xFF) * ai) >> 8);
        Byte bB = (Byte)((((myColor & 0xFF) * ai) >> 8));

我从技术上理解,即在位和二进制级别上发生了什么。我特别了解 'Byte b# = (Byte)((((myColor >> n) & 0xFF)' 部分。我不明白的是预乘法(我的意思是这里的实现,而不是理论)。特别是我想了解 - 所以我的问题:

  1. 为什么 255 右移 8 位,然后除以 alpha?
  2. 为什么每个值都乘以这个结果,然后左移 8 位?

【问题讨论】:

  • 你想在这里做什么?
  • 根据我的问题理解代码吗?

标签: c# pixels writeablebitmapex


【解决方案1】:

这样做是为了在使用整数除法时提高精度。使用整数运算的原因可能是为了速度。

If MyColor = 0xAABBCCDD
AA = 170
BB = 187
CC = 204
DD = 221

Expected values:
bA = 170
bR = 187 * (255 / 170) = 280.5
bG = 204 * (255 / 170) = 306
bB = 221 * (255 / 170) = 331.5 

with integer division 255/170, 255/204, 255/221 will all evaluate to 1 and premultiplication becomes ineffective. 

By using this operation ai = ((255 << 8) / ai)   
with integer division: ai = (255*256)/170 = 384
and subsequent multiplications and shifts gives you a more accurate result.
E.g.
bR = 187 * 384 / 256 =  280
bG = 204 * 384 / 256 =  306
bB = 221 * 384 / 256 =  331

话虽如此,我不相信这是一个很好的 alpha 预乘公式。

如果您有兴趣并了解更多信息,请阅读Fixed Point Arithmetic

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多