【问题标题】:How to strech a bitmap using StretchBlt?如何使用 StretchBlt 拉伸位图?
【发布时间】: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)。再次感谢克里斯蒂 =)

标签: winapi bitmap


【解决方案1】:

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

  1. 使用 BeginPaint() 获取 HDC。
  2. 获取所需的任何其他信息。例如使用GetClientRect()的客户区的尺寸。
  3. 使用函数调用 CreateCompatibleDC() 创建兼容的 DC。
  4. 选择您的位图到兼容的 DC;确保保存 SelectObject() 返回的旧位图。
  5. 使用 BeginPaint() 中的 DC 作为目标和兼容的 DC 作为源调用 StretchBlt()。
  6. 使用 SelectObject() 将旧位图(在步骤 4 中获得)选择回兼容的 DC。
  7. 使用 DeleteDC() 删除兼容的 DC。
  8. 调用 EndPaint()。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    相关资源
    最近更新 更多