1

これは、ピクセル値から 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 ビット左にシフトされるのはなぜですか?
4

1 に答える 1

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

とは言っても、これがアルファ事前乗算の適切な式であるとは確信していません。

興味があり、詳細についてはFixed Point Arithmeticを読んでください。

于 2010-12-16T18:02:32.680 に答える