ソフトウェア開発 Win32プログラミング

PlgBlt関数で任意角度だけ回転する

戻る


あるビットマップオブジェクトをPlgBlt関数で任意角度だけ回転したビットマップを作成するには、 以下のようにするとよいだろう。

HBITMAP CreateRotatedBitmap(HBITMAP hbmSrc, double angle,
                            INT *CenterX, INT *CenterY)
{
    HBITMAP     hbm;
    BITMAP      bm;
    HDC         hDC, hdcSrc;
    POINT       Points[3];
    HGDIOBJ     hbmOld, hbmSrcOld;
    double      theta, s, c, px, py, pxSrc, pySrc, Width, Height;

    if (!GetObject(hbmSrc, sizeof(BITMAP), &bm))
        return NULL;

    if (fmod(angle, 360) == 0)
    {
        hbm = CopyImage(hbmSrc, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
        return hbm;
    }

    theta = angle * M_PI / 180;
    s = sin(theta);
    c = cos(theta);

    Width = fabs(bm.bmWidth * c) + fabs(bm.bmHeight * s);
    Height = fabs(bm.bmWidth * s) + fabs(bm.bmHeight * c);
    px = Width / 2.0;
    py = Height / 2.0;
    pxSrc = bm.bmWidth / 2.0;
    pySrc = bm.bmHeight / 2.0;

    hDC = CreateCompatibleDC(NULL);
    if (hDC == NULL)
        return NULL;

    hbm = Create24BppBitmap(hDC, Width, Height);
    if (hbm == NULL)
    {
        DeleteDC(hDC);
        return NULL;
    }

    hdcSrc = CreateCompatibleDC(NULL);
    if (hdcSrc == NULL)
    {
        DeleteObject(hbm);
        DeleteDC(hDC);
        return NULL;
    }

    hbmOld = SelectObject(hDC, hbm);
    hbmSrcOld = SelectObject(hdcSrc, hbmSrc);

    /* against upper-left corner of source */
    Points[0].x = -pxSrc * c + pySrc * s + px;
    Points[0].y = -pxSrc * s - pySrc * c + py;
    /* against upper-right corner of source */
    Points[1].x = pxSrc * c + pySrc * s + px;
    Points[1].y = pxSrc * s - pySrc * c + py;
    /* against lower-right corner of source */
    Points[2].x = -pxSrc * c - pySrc * s + px;
    Points[2].y = -pxSrc * s + pySrc * c + py;

    SetStretchBltMode(hDC, HALFTONE);
    PlgBlt(hDC, Points, hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight,
           NULL, 0, 0);

    SelectObject(hDC, hbmOld);
    SelectObject(hdcSrc, hbmSrcOld);

    DeleteDC(hDC);
    DeleteDC(hdcSrc);

    if (CenterX)
    {
        *CenterX = px;
    }
    if (CenterY)
    {
        *CenterY = py;
    }

    return hbm;
}

実行結果

確かにあまりきれいじゃない。OpenGLやDirectXを使った方が良いだろう。

ソース: plgblt.zip


戻る

©片山博文MZ
katayama.hirofumi.mz@gmail.com

inserted by FC2 system