Winapi 如何使用StretchBlt拉伸位图?

Winapi 如何使用StretchBlt拉伸位图?,winapi,bitmap,Winapi,Bitmap,因此,我编写了一个加载位图的应用程序。但是我想拉伸加载的位图,使它们的大小相同。我如何用StretchBlt实现这样的事情?下面是我处理位图的函数: hBitmap = (HBITMAP)::LoadImageA(NULL, userSelectedFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); if (hBitmap == NULL) { ::MessageBox(NULL, TEXT("LoadImage Failed

因此,我编写了一个加载位图的应用程序。但是我想拉伸加载的位图,使它们的大小相同。我如何用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;
hBitmap=(hBitmap)::LoadImageA(空,用户选择的文件,图像\u位图,0,0,LR\u LOADFROMFILE);
if(hBitmap==NULL)
{
::MessageBox(空,文本(“LoadImage失败”),文本(“错误”),MB_OK);
返回false;
}
HDC-hLocalDC;
hLocalDC=::CreateCompatibleDC(hWinDC);
if(hLocalDC==NULL)
{
::MessageBox(NULL,文本(“CreateCompatibleDC失败”),文本(“错误”),MB_OK);
返回false;
}
位图;
int-iReturn=GetObject(reinterpret_cast(hBitmap)、sizeof(BITMAP)、reinterpret_cast(&qBitmap));
如果(!i返回)
{
::MessageBox(空,文本(“GetObject失败”),文本(“错误”),MB_OK);
返回false;
}
HBITMAP hOldBmp=(HBITMAP)::选择对象(hLocalDC,HBITMAP);
if(hOldBmp==NULL)
{
::MessageBox(空,文本(“SelectObject失败”),文本(“错误”),MB_OK);
返回false;
}
BOOL qRetBlit=::BitBlt(hWinDC,0,0,qBitmap.bmWidth,qBitmap.bmHeight,hLocalDC,0,0,SRCCOPY);
如果(!qRetBlit)
{
::MessageBox(空,文本(“Blit失败”),文本(“错误”),MB_OK);
返回false;
}
::选择对象(hLocalDC、hOldBmp);
::DeleteDC(hLocalDC);
::删除对象(hBitmap);
返回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;
hBitmap=(hBitmap)::LoadImageA(NULL,myFile,IMAGE\u位图,0,0,LR\u LOADFROMFILE);
//验证是否已加载映像
if(hBitmap==NULL)
{
::MessageBox(空,文本(“LoadImage失败”),文本(“错误”),MB_OK);
返回false;
}
HDC-hLocalDC;
hLocalDC=::CreateCompatibleDC(hWinDC);
//验证是否已创建设备上下文
if(hLocalDC==NULL)
{
::MessageBox(NULL,文本(“CreateCompatibleDC失败”),文本(“错误”),MB_OK);
返回false;
}
位图;
int-iReturn=GetObject(reinterpret_cast(hBitmap)、sizeof(BITMAP)、reinterpret_cast(&qBitmap));
如果(!i返回)
{
::MessageBox(空,文本(“GetObject失败”),文本(“错误”),MB_OK);
返回false;
}
HBITMAP hOldBmp=(HBITMAP)::选择对象(hLocalDC,HBITMAP);
if(hOldBmp==NULL)
{
::MessageBox(空,文本(“SelectObject失败”),文本(“错误”),MB_OK);
返回false;
}
/*BOOL qRetBlit=::BitBlt(hWinDC、xPos、yPos、qBitmap.bmWidth、qBitmap.bmHeight、hLocalDC、0、0、SRCCOPY);
如果(!qRetBlit)
{
::MessageBox(空,文本(“Blit失败”),文本(“错误”),MB_OK);
返回false;
}*/
sx=GetSystemMetrics(SM_CXSCREEN);
sy=GetSystemMetrics(SM_CXSCREEN);
BOOL qStretchBlit=拉伸BLT(hWinDC,0,0,sx/2,sy/2,hLocalDC,0,0,sx,sy,SRCCOPY);
如果(!qstretchbrit)
{
MessageBox(空,文本(“StretchBlt失败”),文本(“错误”),MB_OK);
返回false;
}
//调整定位(不完美)
如果(iOldCounter>iCounter)
{
xPos+=移动X位置;
如果(xPos>=新行位置)
{
xPos=0;
yPos+=移动位置;
}
}
::选择对象(hLocalDC、hOldBmp);
::DeleteDC(hLocalDC);
::删除对象(hBitmap);
返回true;

想法?

我已经解决了最初的问题。以下是我采取的步骤:

  • 使用BeginPaint()获取HDC
  • 获取所需的任何其他信息。例如,使用GetClientRect()设置客户端区域的维度
  • 使用函数调用CreateCompatibleDC()创建兼容的DC
  • 将位图选择到兼容的DC中;确保保存SelectObject()返回的旧位图
  • 使用来自BeginPaint()的DC作为目标并将兼容DC作为源调用StretchBlt()
  • 使用SelectObject()将旧位图(在步骤4中获得)选择回兼容的DC
  • 使用DeleteDC()删除兼容的DC
  • 调用EndPaint()

  • 您的意思是“将
    BitBlt
    替换为
    StrechBlt
    ”(因为您已经在使用前者)。你查过了吗(虽然有点长)?@CristiFati我查过,但像这样一个巨大的例子,我真的无法完全理解。我希望这里有人能给我一个提示,但显然没有人喜欢WinAPI(;p)我确实喜欢WinAPI:d。在
    hWinDC
    上绘制时,您是否尝试过用
    StretchBlt
    替换
    BitBlt
    (不要忘记另外两个参数)?此外,我不确定StretchBlt使用的插值技术是什么,但作为替代方法,您可以查看使用最近邻(最简单也是最差)手动缩放图像的方法@CristiFati我唯一不喜欢WinAPI的地方是它的语法,而我不喜欢这种特殊语言,因为它在实现加载多个图像和拉伸图像等简单功能方面做了大量的工作。尽管如此,我还是要感谢你试图帮助我,我已经解决了这个问题。事实证明,我需要使用来自BeginPaint()的DC作为目标,使用兼容的DC作为源。我使用DC from BeginPaint()作为目标和源(太愚蠢了:p)。再次感谢你,克里斯蒂=)