2017-03-20 52 views
0

所以我寫了一個加載位圖的應用程序。但我想拉伸加載的位圖,使它們都具有相同的大小。我怎樣才能用StretchBlt來實現這樣的事情?這是我的功能,處理位圖:如何使用StretchBlt拉伸位圖?

hBitmap = (HBITMAP)::LoadImageA(NULL, userSelectedFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 

    if (hBitmap == NULL) 
    { 
     ::MessageBox(NULL, TEXT("LoadImage Failed"), TEXT("Error"), MB_OK); 
     return false; 
    } 

    HDC hLocalDC; 
    hLocalDC = ::CreateCompatibleDC(hWinDC); 
    if (hLocalDC == NULL) 
    { 
     ::MessageBox(NULL, TEXT("CreateCompatibleDC Failed"), TEXT("Error"), MB_OK); 
     return false; 
    } 

    BITMAP qBitmap; 
    int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP), reinterpret_cast<LPVOID>(&qBitmap)); 
    if (!iReturn) 
    { 
     ::MessageBox(NULL, TEXT("GetObject Failed"), TEXT("Error"), MB_OK); 
     return false; 
    } 

    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap); 
    if (hOldBmp == NULL) 
    { 
     ::MessageBox(NULL, TEXT("SelectObject Failed"), TEXT("Error"), MB_OK); 
     return false; 
    } 

    BOOL qRetBlit = ::BitBlt(hWinDC, 0, 0, qBitmap.bmWidth, qBitmap.bmHeight, hLocalDC, 0, 0, SRCCOPY); 
    if (!qRetBlit) 
    { 
     ::MessageBox(NULL, TEXT("Blit Failed"), TEXT("Error"), MB_OK); 
     return false; 
    } 

    ::SelectObject(hLocalDC, hOldBmp); 
    ::DeleteDC(hLocalDC); 
    ::DeleteObject(hBitmap); 
    return true; 

將我必須替換StretchBlt與BitBlt?

更新:我已經設法讓StretchBlt工作,但顯然我的所有圖像都互相重疊。以下是目前爲止的代碼:

hBitmap = (HBITMAP)::LoadImageA(NULL, myFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 

// Verify that the image was loaded 
if (hBitmap == NULL) 
{ 
    ::MessageBox(NULL, TEXT("LoadImage Failed"), TEXT("Error"), MB_OK); 
    return false; 
} 
HDC hLocalDC; 
hLocalDC = ::CreateCompatibleDC(hWinDC); 
// Verify that the device context was created 
if (hLocalDC == NULL) 
{ 
    ::MessageBox(NULL, TEXT("CreateCompatibleDC Failed"), TEXT("Error"), MB_OK); 
    return false; 
} 
BITMAP qBitmap; 
int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP), reinterpret_cast<LPVOID>(&qBitmap)); 
if (!iReturn) 
{ 
    ::MessageBox(NULL, TEXT("GetObject Failed"), TEXT("Error"), MB_OK); 
    return false; 
} 

HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap); 
if (hOldBmp == NULL) 
{ 
    ::MessageBox(NULL, TEXT("SelectObject Failed"), TEXT("Error"), MB_OK); 
    return false; 
} 
/*BOOL qRetBlit = ::BitBlt(hWinDC, xPos, yPos, qBitmap.bmWidth, qBitmap.bmHeight, hLocalDC, 0, 0, SRCCOPY); 
if (!qRetBlit) 
{ 
    ::MessageBox(NULL, TEXT("Blit Failed"), TEXT("Error"), MB_OK); 
    return false; 
}*/ 
sx = GetSystemMetrics(SM_CXSCREEN); 
sy = GetSystemMetrics(SM_CXSCREEN); 

BOOL qStretchBlit = StretchBlt(hWinDC, 0, 0, sx/2, sy/2, hLocalDC, 0, 0, sx, sy, SRCCOPY); 
if (!qStretchBlit) 
{ 
    MessageBox(NULL, TEXT("StretchBlt Failed"), TEXT("Error"), MB_OK); 
    return false; 
} 

// Adjust positioning (not perfect) 
if (iOldCounter > iCounter) 
{ 
    xPos += MOVE_X_POS; 
    if (xPos >= NEW_ROW_POS) 
    { 
     xPos = 0; 
     yPos += MOVE_Y_POS; 
    } 
} 
::SelectObject(hLocalDC, hOldBmp); 
::DeleteDC(hLocalDC); 
::DeleteObject(hBitmap); 
return true; 

想法?

+0

你的意思是「用'StrechBlt'替換'BitBlt'」(因爲你已經在使用前者)。你檢查[MSDN:縮放圖像](https://msdn.microsoft.com/en-us/library/windows/desktop/dd162950(v = vs.85).aspx)(雖然它有點長)? – CristiFati

+0

@CristiFati我有,但喜歡它是這樣一個巨大的例子,我真的不明白這一切。我希望這裏有人會給我一個提示,但顯然沒有人喜歡WinAPI(; p) – WaveOnyx

+0

我喜歡_WinAPI_:d。在hWinDC上繪畫時,你是否嘗試用'StretchBlt'替換'BitBlt'(別忘了2個額外的參數)?此外,我不確定什麼插值技術'StretchBlt'使用,但作爲替代,你可以看看[SO:這個答案](https://stackoverflow.com/questions/41861274/scaling-up-an-image- using-nearest-neighbor/41879669#41879669),它使用_nearest neighbor_(這是最簡單但也是最差的)手動縮放圖像。 – CristiFati

回答

0

我已經解決了我最初的問題。下面是我採取的步驟:

  1. 使用BeginPaint()獲取HDC。
  2. 獲取所需的任何附加信息。例如,使用GetClientRect()的客戶區域的維度。
  3. 使用函數調用CreateCompatibleDC()創建兼容的DC。
  4. 選擇您的位圖到兼容的DC;確保保存由SelectObject()返回的舊位圖。
  5. 使用來自BeginPaint()的DC作爲目標並將兼容的DC作爲源調用StretchBlt()。
  6. 使用SelectObject()將舊位圖(在步驟4中獲得)選回到兼容的DC中。
  7. 使用DeleteDC()刪除兼容的DC。
  8. Call EndPaint()。