【发布时间】:2017-08-11 11:40:03
【问题描述】:
所以我编写了一个加载位图的应用程序。但我想拉伸加载的位图,使它们都具有相同的大小。我怎样才能用 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;
我必须用 BitBlt 替换 StretchBlt 吗?
更新:我已经设法让 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;
想法?
【问题讨论】:
-
您的意思是“将
BitBlt替换为StrechBlt”(因为您已经在使用前者)。你检查过MSDN: Scaling an Image(虽然有点长)? -
@CristiFati 我有,但就像这是一个如此巨大的例子,我真的无法理解所有这些。我希望这里有人能给我一个提示,但显然没有人喜欢 WinAPI (;p)
-
我喜欢 WinAPI :d。在
hWinDC上绘画时,您是否尝试将BitBlt替换为StretchBlt(不要忘记额外的2 个参数)?另外,我不确定StretchBlt使用什么插值技术,但作为替代方案,您可以查看SO: this answer,它使用 最近邻 手动缩放图像(这是最简单但也是最差的)。 -
@CristiFati 我不喜欢 WinAPI 的唯一一点是它的语法和为实现加载多个图像和拉伸图像等简单的事情而进行的大量工作是我不喜欢这种特定语言的地方。尽管如此,我还是要感谢你试图帮助我,我已经解决了这个问题。事实证明,我需要使用 BeginPaint() 中的 DC 作为目标,并使用兼容的 DC 作为源。我使用 BeginPaint() 中的 DC 作为目标和源(太愚蠢了:p)。再次感谢克里斯蒂 =)