0

我有一个 2752x2200 的位图图像。我只能在我的 MFC 对话框中显示 1/3(对于明显的尺寸问题),所以如果我不缩放图像,我只会得到左上角的 917x733 块(左上角的 1/3 块)。我想将图像缩小 3 倍,以便整个图像显示在图像大小的 1/3 区域中。我已经像这样设置了灰度位图:

    //////////////////////////////////////////////////////////////////////////
    //////////  Setup Bitmap  ////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////

    //// FILEHEADER ////
    BITMAPFILEHEADER* bf = new BITMAPFILEHEADER;
    bf->bfType = 0x4d42;
    bf->bfSize = 6054400 + 54 + sizeof(BITMAPINFO);
    bf->bfOffBits = 54;

    //// INFOHEADER ////
    BITMAPINFOHEADER* bi = new BITMAPINFOHEADER;
    bi->biSize = 40;
    bi->biWidth = 2752;
    bi->biHeight = -2200;
    bi->biPlanes = 1;
    bi->biBitCount = 8;
    bi->biCompression = 0;
    //bi->biSizeImage = 6054400; //not required
    bi->biXPelsPerMeter = 2835;
    bi->biYPelsPerMeter = 2835;
    bi->biClrUsed = 0;
    bi->biClrImportant = 0;

    //// INFO ////
    BITMAPINFO* pbmi = (BITMAPINFO*)alloca( sizeof(BITMAPINFOHEADER) +   
        sizeof(RGBQUAD)*256);
    pbmi->bmiHeader.biSize = sizeof (pbmi->bmiHeader);
    pbmi->bmiHeader.biWidth = 2752;
    pbmi->bmiHeader.biHeight = -2200;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 8;
    pbmi->bmiHeader.biCompression = BI_RGB;
    pbmi->bmiHeader.biSizeImage = 0;
    pbmi->bmiHeader.biXPelsPerMeter = 14173;
    pbmi->bmiHeader.biYPelsPerMeter = 14173;
    pbmi->bmiHeader.biClrUsed = 0;
    pbmi->bmiHeader.biClrImportant = 0;
    //create grayscale color palette
    for(int i=0; i<256; i++)
    {
        pbmi->bmiColors[i].rgbRed = i;
        pbmi->bmiColors[i].rgbGreen = i;
        pbmi->bmiColors[i].rgbBlue = i;
        pbmi->bmiColors[i].rgbReserved = 0;
    }

    //// IMAGE DATA ////
    pFrame->GetImage(m_imageData);

    //////////////////////////////////////////////////////////////////////
    ////// Create image that's printed to dialog box /////////////////////
    //////////////////////////////////////////////////////////////////////
    HDC hdc = ::GetDC(NULL);  
    hbit = CreateDIBitmap(hdc, bi, CBM_INIT, m_imageData,
       pbmi, DIB_RGB_COLORS);

然后我将位图绘制到我的对话框上,如下所示:

    BITMAP* bi = new BITMAP;
    CBitmap bmp;
    bmp.Attach(hbit);
    CClientDC dc(pWnd);
    CDC bmDC;
    bmDC.CreateCompatibleDC(&dc);
    CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
    bmp.GetBitmap(bi);
    dc.StretchBlt(384,21,bi->bmWidth,bi->bmHeight,&bmDC,0,0,
        bi->bmWidth,bi->bmHeight,SRCCOPY);
    bmDC.SelectObject(pOldbmp);

使用此代码,图像看起来不错,但它只是完整图像的左上角块:

图像1

在我尝试缩小图像时,我改变了这一行:

        dc.StretchBlt(384,21,bi->bmWidth,bi->bmHeight,&bmDC,0,0,
            bi->bmWidth,bi->bmHeight,SRCCOPY);

到:

        dc.StretchBlt(384,21,bi->bmWidth/3,bi->bmHeight/3,&bmDC,0,0,
            bi->bmWidth,bi->bmHeight,SRCCOPY); // 1/3 original size

现在我的输出看起来缩小了,它显示了整个图像(好),但一切看起来都扭曲了(坏):

图2

(注意图像边界周围的圆环。那些不应该在那里,当你真正看到我的图像流的实时视频时,它们会跳动并基本上破坏图像)。

我的问题是: 是什么导致了这种失真,有什么简单的方法可以解决吗?

编辑:尝试 StretchDIBits() 后:

    StretchDIBits(dc.m_hDC, 384, 21, bi->bmWidth/3, bi->bmHeight/3, 0, 
            0,bi->bmWidth,bi->bmHeight, myObv->GetImageData(), 
            myObv->GetPBMI(), DIB_RGB_COLORS, SRCCOPY);

我的输出看起来像这样:

i.imgur.com/DA49P8x.png

4

2 回答 2

3

如果您正在缩放位图,windows api 可能在视觉上表现不佳,因为它旨在优化性能。在 StretchBlt 之前添加以下行以增强位图操作:

SetStretchBltMode(dc.m_hDC, HALFTONE);
于 2013-02-16T05:33:31.163 回答
2

而不是StretchBLT尝试StretchDIBits

StretchDIBits(dc.m_hDC, 384, 21, bi->bmWidth/3, bi->bmHeight/3, 0, 0,
              bi->bmWidth, bi->bmHeight, m_imageData, pbmi, DIB_RGB_COLORS, SRCCOPY);
于 2013-02-15T18:21:47.387 回答