C# WriteableBitmapEx 像素预乘位移位

发布于 2024-10-08 09:53:22 字数 734 浏览 0 评论 0原文

这是关于从像素值中提取 RGB。这是代码片段:

        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 位?

This is about extracting the RGB from a pixel value. Here is the code snippet:

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

I understand technically, i.e. at the level of bits, and binary what is going on. I understand in particular the 'Byte b# = (Byte)((((myColor >> n) & 0xFF)' parts. What I do not understand is the premultiplication (I mean the implementation here, not the theory). In particular I want to understand - and so to my questions:

  1. Why is 255 being shifted by 8 bits to the right and then devided by the alpha?
  2. Why is each value being multiplied by the result of this and then shifted 8 bits to the left?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

糖果控 2024-10-15 09:53:22

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

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 预乘公式。

如果您有兴趣,请阅读定点算术了解更多信息

This is done to increase the precision while using integer division. Reason to use integer operations could be for speed.

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

Having said that I'm not convinced that this is a good formula for alpha premultiply.

If you are interested, and for more information read up on Fixed Point Arithmetic

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文