C # WriteableBitmapEx Пиксельное предварительное умножение битового сдвига - PullRequest
1 голос
/ 16 декабря 2010

Речь идет о выделении 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 бит вправо, а затем делится на альфа?
  2. Почему каждое значение умножается на результат этого, а затем сдвигается на 8 бит влево?

1 Ответ

1 голос
/ 16 декабря 2010

Это сделано для увеличения точности при использовании целочисленного деления. Причиной использования целочисленных операций может быть скорость.

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

Сказав, что я не уверен, что это хорошая формула для предварительного умножения альфа.

Если вы заинтересованы, и для получения дополнительной информации читайте на Арифметика с фиксированной точкой

...