如何通过StretchBlt函数调整图像大小?解决图像超出控件问题
问题解决:用StretchBlt适配图像到图片控件
先修正你代码里的几个核心问题,就能让图像正确适配图片控件:
错误1:获取的是主对话框而非图片控件
你当前用AfxGetApp()->GetMainWnd()拿到的是整个对话框窗口,所以绘制会铺满整个对话框。需要改成获取目标图片控件的窗口指针,比如假设图片控件ID是IDC_PICTURE:CWnd* pPictureBox = GetDlgItem(IDC_PICTURE); // 替换成你的图片控件实际ID错误2:未正确获取控件的显示区域
你代码里的rect变量没有定义,需要先获取图片控件的客户区矩形:CRect rect; pPictureBox->GetClientRect(&rect);错误3:重复绘制导致StretchBlt失效
你同时调用了StretchBlt和img.Draw,Draw会按原图大小直接绘制,覆盖了拉伸后的效果,必须去掉img.Draw这一行。错误4:图像数据拷贝代码不完整
你当前的memcpy_s只是声明,没有实际执行拷贝操作,需要补充把imageRGB的数据复制到CImage的缓冲区里:BYTE* pImgBits = img.GetBits(); memcpy_s(pImgBits, img.GetPitch() * img.GetHeight(), imageRGB.GetBuffer(), imageRGB.GetWidth() * imageRGB.GetHeight());
修正后的完整代码片段:
void BaslerCode::OnImageGrabbed(CInstantCamera& camera, const CGrabResultPtr& ptrGrabResult) { if (ptrGrabResult->GrabSucceeded()) { CImage img; // 创建和imageRGB同尺寸的8位图像 img.Create(imageRGB.GetWidth(), imageRGB.GetHeight(), 8); // 把imageRGB的数据拷贝到CImage缓冲区 BYTE* pImgBits = img.GetBits(); memcpy_s(pImgBits, img.GetPitch() * img.GetHeight(), imageRGB.GetBuffer(), imageRGB.GetWidth() * imageRGB.GetHeight()); // 获取图片控件窗口(替换成你的控件ID) CWnd* pPictureBox = GetDlgItem(IDC_PICTURE); if (pPictureBox == nullptr) return; CDC* pDC = pPictureBox->GetDC(); if (pDC == nullptr) return; CRect rect; pPictureBox->GetClientRect(&rect); // 拉伸图像到控件的整个客户区 img.StretchBlt(pDC->m_hDC, 0, 0, rect.Width(), rect.Height(), 0, 0, imageRGB.GetWidth(), imageRGB.GetHeight(), SRCCOPY); pPictureBox->ReleaseDC(pDC); } }
关键说明:
StretchBlt的参数要明确:前四个是目标区域(控件的坐标和尺寸),接下来四个是源图像的完整区域(从(0,0)到图像的宽高),这样就能把整张图像拉伸适配到控件大小。- 确保图片控件的属性设置正确,比如边框、对齐方式等,避免额外的显示问题。
内容的提问来源于stack exchange,提问作者Sanghyeon Woo
相关产品推荐
相关产品推荐

