簡體   English   中英

如何在Win32 C ++中從Spritesheet中提取位圖?

[英]How to extract bitmap from spritesheet in Win32 C++?

我正在嘗試根據西裝和等級從紙牌小片中加載單個紙牌,但是我不確定如何從源圖像中切出矩形坐標來構造新的位圖對象。 我目前正在使用<windows.h>並試圖找到一種簡單的方法來完成此任務。 我正在尋找這樣的東西:

HBITMAP* twoOfHearts = CutOutFromImage(sourceImage, new Rectangle(0, 0, 76, 116));

來源: http//i.stack.imgur.com/WZ9Od.gif

這是我前一周為大致相同的任務而玩的一項功能。 就我而言,我想返回可以與FillRect一起使用的HBRUSH。 在這種情況下,我們仍然需要創建感興趣區域的位圖,然后再從中創建畫筆。

在您的情況下,只需返回dstBmp spriteSheet是已加載256x256 Spritesheet的全局對象。 我已經將精靈的大小硬編碼為16x16,您需要將其更改為81x117。

這是一些獲取所需區域副本的代碼,還有更多使用這些“郵票”繪制級別圖的代碼。 就是說-這種方法存在各種各樣的問題。 速度是一個因素,過度的工作是影響第一因素的另一個因素。 最后,滾動這樣繪制的窗口會產生偽影。

// grabs a 16x16px section from the spriteSheet HBITMAP
HBRUSH getSpriteBrush(int col, int row)
{
    HDC memDC, dstDC, curDC;
    HBITMAP oldMemBmp, oldDstBmp, dstBmp;
    curDC = GetDC(HWND_DESKTOP);

    memDC = CreateCompatibleDC(NULL);
    dstDC = CreateCompatibleDC(NULL);

    dstBmp = CreateCompatibleBitmap(curDC, 16, 16);
    int xOfs, yOfs;
    xOfs = 16 * col;
    yOfs = 16 * row;

    oldMemBmp = (HBITMAP)SelectObject(memDC, spriteSheet);
    oldDstBmp = (HBITMAP)SelectObject(dstDC, dstBmp);
    BitBlt(dstDC,0,0,16,16, memDC, xOfs,yOfs, SRCCOPY);

    SelectObject(memDC, oldMemBmp);
    SelectObject(dstDC, oldDstBmp);
    ReleaseDC(HWND_DESKTOP, curDC);
    DeleteDC(memDC);
    DeleteDC(dstDC);

    HBRUSH result;
    result = CreatePatternBrush(dstBmp);
    DeleteObject(dstBmp);
    return result;
}

void drawCompoundSprite(int x, int y, HDC paintDC, char *tileIndexes, int numCols, int numRows)
{
    int mapCol, mapRow;
    HBRUSH curSprite;
    RECT curDstRect;

    for (mapRow=0; mapRow<numRows; mapRow++)
    {
        for (mapCol=0; mapCol<numCols; mapCol++)
        {
            int curSpriteIndex = tileIndexes[mapRow*numCols + mapCol];
            int spriteX, spriteY;

            spriteX = curSpriteIndex % 16;
            spriteY = curSpriteIndex / 16;

            curDstRect.left = x + 16*mapCol;
            curDstRect.top = y + 16 * mapRow;
            curDstRect.right = curDstRect.left + 16;
            curDstRect.bottom = curDstRect.top + 16;
            curSprite = getSpriteBrush(spriteX, spriteY);
            FillRect(paintDC, &curDstRect, curSprite);
            DeleteObject(curSprite);
        }
    }
}

在此處輸入圖片說明

此后的功能已替換為以下功能:

void drawCompoundSpriteFast(int x, int y, HDC paintDC, unsigned char *tileIndexes, int numCols, int numRows, pMapInternalData mData)
{

    int mapCol, mapRow;
    HBRUSH curSprite;
    RECT curDstRect;
    HDC memDC;
    HBITMAP oldBmp;
    memDC = CreateCompatibleDC(NULL);
    oldBmp = (HBITMAP)SelectObject(memDC, mData->spriteSheet);

    for (mapRow=0; mapRow<numRows; mapRow++)
    {
        for (mapCol=0; mapCol<numCols; mapCol++)
        {
            int curSpriteIndex = tileIndexes[mapRow*numCols + mapCol];
            int spriteX, spriteY;

            spriteX = curSpriteIndex % mData->tileWidth;
            spriteY = curSpriteIndex / mData->tileHeight


// Draw sprite as-is
//            BitBlt(paintDC, x+16*mapCol, y+16*mapRow,
//                   mData->tileWidth, mData->tileHeight,
//                   memDC,
//                   spriteX * 16, spriteY*16,
//                   SRCCOPY);

// Draw sprite with magenta rgb(255,0,255) areas treated as transparent (empty)
            TransparentBlt(
                           paintDC,
                           x+mData->tileWidth*mapCol, y+mData->tileHeight*mapRow,
                           mData->tileWidth, mData->tileHeight,

                           memDC,
                           spriteX * mData->tileWidth, spriteY*mData->tileHeight,
                           mData->tileWidth, mData->tileHeight,
                           RGB(255,0,255)
                           );
        }
    }
    SelectObject(memDC, oldBmp);
    DeleteObject(memDC);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM