C++ 缩放位图输出会扭曲图像
我有一个2752x2200位图图像。我只能在MFC对话框中显示它的1/3(对于明显的大小问题),因此如果我不缩放图像,我只能得到左上角的917x733块(左上角的1/3块)。我想将图像缩小3倍,这样整个图像就会显示在图像1/3大小的区域中。我已按如下方式设置灰度位图:C++ 缩放位图输出会扭曲图像,c++,image,mfc,bitmap,C++,Image,Mfc,Bitmap,我有一个2752x2200位图图像。我只能在MFC对话框中显示它的1/3(对于明显的大小问题),因此如果我不缩放图像,我只能得到左上角的917x733块(左上角的1/3块)。我想将图像缩小3倍,这样整个图像就会显示在图像1/3大小的区域中。我已按如下方式设置灰度位图: ////////////////////////////////////////////////////////////////////////// ////////// Setup Bitmap //////
//////////////////////////////////////////////////////////////////////////
////////// 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);
使用此代码,图像看起来不错,但它只是完整图像的左上角块:
在尝试缩小图像时,我更改了行:
dc.StretchBlt(384,21,bi->bmWidth,bi->bmHeight,&bmDC,0,0,
bi->bmWidth,bi->bmHeight,SRCCOPY);
致:
现在,我的输出看起来缩小了,它显示了整个图像(好),但所有内容看起来都扭曲了(坏):
(注意图像边界周围的圆环。这些圆环不应该在那里,当你真正看到我的图像流的实时视频时,它们会跳动,基本上破坏了图像)
我的问题是:是什么导致了这种失真?我能做些简单的事情来修复它吗
编辑:尝试StretchDIBits()后:
我的输出如下所示:
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);
i、 imgur.com/DA49P8x.png而不是
StretchBLT
尝试:
尝试以下操作,而不是
StretchBLT
:
如果要缩放位图,windows api可能会在视觉上表现不佳,因为它是为优化性能而设计的。在StretchBlt之前添加以下行以增强位图操作:
SetStretchBltMode(dc.m_hDC, HALFTONE);
如果要缩放位图,windows api可能会在视觉上表现不佳,因为它是为优化性能而设计的。在StretchBlt之前添加以下行以增强位图操作:
SetStretchBltMode(dc.m_hDC, HALFTONE);
有没有办法在某处发布100%大小的屏幕截图?我怀疑你看到的是图像中固有的噪声混叠,但无法确定此处显示的调整大小的图像。没关系,我发现你可以在新选项卡中打开图像,并以100%的速度看到它。问题不在于混叠,而在于后期处理——调色板被减少到非常少的颜色。有没有办法在某个地方发布100%大小的屏幕截图?我怀疑你看到的是图像中固有的噪声混叠,但无法确定此处显示的调整大小的图像。没关系,我发现你可以在新选项卡中打开图像,并以100%的速度看到它。问题不在于混叠,而在于后期处理——调色板被缩减为非常少量的颜色。@xcdemon05,这很奇怪。我唯一能想到的另一件事是将
biClrUsed
和biclrementant
设置为256,但我不希望这会改变任何事情。@xcdemon05我最新的想法是,您可能有调色板损坏。尝试在StretchDIBits之后测试调色板,确保它仍然是灰度调色板。@xcdemon05,这很奇怪。我唯一能想到的另一件事是将biClrUsed
和biclrementant
设置为256,但我不希望这会改变任何事情。@xcdemon05我最新的想法是,您可能有调色板损坏。尝试在StretchDIBits之后测试调色板,以确保它仍然是灰度调色板。这里可能有一些内容,但对于灰度调色板,我建议使用COLORONCOLOR
。@MarkRansom-是的,我认为你是对的,它更适合xcdemon05的使用,我只是从我的旧代码中选择了它。这里可能有一些内容,但对于灰度调色板,我建议改为COLORONCOLOR
。@markransem-是的,我认为你是对的,它更适合xcdemon05的使用,我只是从我的旧代码中选择它。
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);
SetStretchBltMode(dc.m_hDC, HALFTONE);