プログラミングメモ →目次

色の表現(VC++)

Color

ウィンドウズの色は、三原色のそれぞれの色を1バイトずつで管理されています。COLORREFというデータ型で色を保存します。モニターのスクリーンは発光体のもので、下記のように赤、緑、青で色情報を管理されています。

typedef DWORD COLORREF;
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))

光の場合の三原色は、赤(Red, 0x000000ff)、緑(Green, 0x0000ff00)、青(Blue, 0x00ff0000)で、
赤+緑+青=白(White, 0x00ffffff)
絵の具の場合は、ピンク(Magenta, 0x00ff00ff)、黄(Yellow, 0x0000ffff)、水色(Cyan, 0x00ffff00)で、
ピンク・黄・水色=黒(Black, 0x00000000)

例:論理演算で、三原色での色合成図を表示する。

ソース:

void CColorTestView::OnDraw(CDC* pDC)
{
    CRect r;
    GetClientRect(&r); r.right /= 2; 
    CBrush brushRed((COLORREF)0x000000ff);
    CBrush brushGreen((COLORREF)0x0000ff00);
    CBrush brushBlue((COLORREF)0x00ff0000);
    pDC->FillSolidRect(&r, (COLORREF)0x00000000);
    pDC->SetROP2(R2_MERGEPEN);
    int delta = 100;
    for (int i = 0; i < 360; i += 120)
    {
        int cy = (int)(r.bottom / 2 - 80 * cos(i * atan(1.0) / 45));
        int cx = (int)(r.right / 2 - 80 * sin(i * atan(1.0) / 45));
        if (i == 0)
            pDC->SelectObject(&brushRed);
        else if (i == 120)
            pDC->SelectObject(&brushGreen);
        else
            pDC->SelectObject(&brushBlue);
        pDC->Ellipse(cx - delta, cy - delta, cx + delta, cy + delta);
    }

    CBrush brushMagenta((COLORREF)0x00ff00ff);
    CBrush brushYellow((COLORREF)0x0000ffff);
    CBrush brushCyan((COLORREF)0x00ffff00);
    CPen penWhite(PS_SOLID, 0, (COLORREF)0x00ffffff);
    pDC->SelectObject(&penWhite);
    pDC->SetROP2(R2_MASKPEN);
    for (i = 0; i < 360; i += 120)
    {
        int cy = (int)(r.bottom / 2 - 80 * cos(i * atan(1.0) / 45));
        int cx = (int)(r.right * 3 / 2 - 80 * sin(i * atan(1.0) / 45));
        if (i == 0)
            pDC->SelectObject(&brushMagenta);
        else if (i == 120)
            pDC->SelectObject(&brushYellow);
        else
            pDC->SelectObject(&brushCyan);
        pDC->Ellipse(cx - delta, cy - delta, cx + delta, cy + delta);
    }
}