3

ARGB カラーをその形式に変換する必要が生じるまで、デバイスのコントロール クラスを作成していました。最初に、私はこの関数を書きました(うまくいきました):

private static int convertFormat(System.Drawing.Color c)
{
    String all;

    int a = (int)((float)c.A / 31.875);

    if (a == 0)
        a = 1;

    all = a.ToString() + c.B.ToString("X").PadLeft(2, '0') + c.G.ToString("X").PadLeft(2, '0') + c.R.ToString("X").PadLeft(2, '0');

    int num = int.Parse(all, System.Globalization.NumberStyles.AllowHexSpecifier);

    return num;
}

しかし、それはとても醜いので、もっとエレガントなソリューションを書きたかったのです。そこで、0 から 50 までのすべての組み合わせを試して、正しい値を取得するためにいくつかのことを行いました。

private static int convertFormatShifting(System.Drawing.Color c)
{
    int alpha = (int)Math.Round((float)c.A / 31.875);

    int a = Math.Max(alpha,1);

    return (a << 24) | (c.B << 48) | (c.G << 40) | (c.R << 32);
}

動作します!

しかし今、これらが正しいシフト値である理由を誰かに説明してもらいたいです。

4

2 に答える 2

9

最も紛らわしいシフト値は次のとおりです。

return (a << 24) | (c.B << 16) | (c.G << 8) | (c.R << 0);
// Of course there's no need to shift by zero  ^^^^^^^^

値が機能する理由は、シフト演算子modが右側にあり、オペランドのビット長が左側にあるためです。つまり、次のすべてのシフトは互いに同等です。

c.G << 8
c.G << 40
c.G << 72
c.G << 104
...
于 2013-10-11T13:41:17.157 に答える
0

Wikipediaによると、RGBA 形式は次の規則に従います。

semantics alpha | red | green | blue
bits      31-24 |23-16|15 -  8|7 - 0

これは、あなたのシフトが行うことと似ています。ビットを左に移動し、ビット賢明な or で連結します。次に、関数が返すと予想されるものを見てください( 内の色の順序は何ですかint)。

于 2013-10-11T13:50:08.293 に答える