image - 在优化校准中计算图像的正确位置,并正确绘制背景(在 MFC 对话框中)
问题描述
我有这个对话框:
这是对话框的 RC:
IDD_DIALOG_SPECIAL_EVENT_VIDEOCONF DIALOGEX 0, 0, 541, 233
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Special Event — Videoconference"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "Details",IDC_STATIC,7,7,301,201
LTEXT "Path to image to display:",IDC_STATIC,15,22,80,8
CONTROL "",IDC_BROWSE_SPECIAL_EVENT_VIDEOCONF_PATH_IMAGE,
"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,14,32,288,14
LTEXT "50%",IDC_STATIC,13,49,16,8
CONTROL "",IDC_SLIDER_SPECIAL_EVENT_VIDEOCONF_IMAGE_WIDTH,
"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,8,58,294,15
LTEXT "Width of image:",IDC_STATIC,15,77,52,8
LTEXT "%",IDC_STATIC_SPECIAL_EVENT_VIDEOCONF_IMAGE_WIDTH,70,77,19,8
LTEXT "Text to display before the image:",IDC_STATIC,15,97,108,8
EDITTEXT IDC_EDIT_SPECIAL_EVENT_VIDEOCONF_TEXT_BEFORE_IMAGE,14,109,288,37,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
LTEXT "Text to display after the image:",IDC_STATIC,16,152,102,8
EDITTEXT IDC_EDIT_SPECIAL_EVENT_VIDEOCONF_TEXT_AFTER_IMAGE,14,163,288,37,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
DEFPUSHBUTTON "OK",IDOK,198,212,50,14
PUSHBUTTON "Cancel",IDCANCEL,252,212,50,14
LTEXT "100%",IDC_STATIC,287,48,20,8
GROUPBOX "Image Preview",IDC_STATIC,314,7,224,201
CONTROL "",IDC_STATIC_IMAGE_PREVIEW,"Static",SS_OWNERDRAW,321,18,210,181
END
它上面有一个优化校准。我已将其设置为Owner Draw。CImage
当用户浏览文件时,对话框将图像加载到 a中:
void CSpecialEventVideoconferenceInfoDlg::OnEnChangeBrowseSpecialEventVideoconfPathImage()
{
CString strImagePath;
GetDlgItemText(IDC_BROWSE_SPECIAL_EVENT_VIDEOCONF_PATH_IMAGE, strImagePath);
m_imgPreview.Load(strImagePath);
}
而且,渲染是这样的:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (nIDCtl == IDC_STATIC_IMAGE_PREVIEW && !m_imgPreview.IsNull())
{
SetStretchBltMode(lpDrawItemStruct->hDC, HALFTONE);
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioDest)
rectDraw.SetRect(0, 0, rectDraw.right, rectDraw.right / nRatioImage);
else if (nRatioImage < nRatioDest)
rectDraw.SetRect(0, 0, rectDraw.bottom * nRatioImage, rectDraw.bottom);
m_imgPreview.Draw(lpDrawItemStruct->hDC, rectDraw);
}
}
我在这里有两个问题到目前为止我无法解决:
- 图像未集中绘制到我的容器中:
- 如果我决定使用另一个图像,图片控件不会正确擦除背景:
更新
如果我像这样调整代码:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (nIDCtl == IDC_STATIC_IMAGE_PREVIEW && !m_imgPreview.IsNull())
{
SetStretchBltMode(lpDrawItemStruct->hDC, HALFTONE);
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)GetStockObject(WHITE_BRUSH));
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioDest)
rectDraw.SetRect(0, 0, rectDraw.right, rectDraw.right / nRatioImage);
else if (nRatioImage < nRatioDest)
rectDraw.SetRect(0, 0, rectDraw.bottom * nRatioImage, rectDraw.bottom);
m_imgPreview.Draw(lpDrawItemStruct->hDC, rectDraw);
}
}
...它解决了第二个问题。它使用FillRect
. 所以它只是改变我的代码来集中图片来解决。
解决方案
这是我的解决方案:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (nIDCtl == IDC_STATIC_IMAGE_PREVIEW && !m_imgPreview.IsNull())
{
SetStretchBltMode(lpDrawItemStruct->hDC, HALFTONE);
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)GetStockObject(WHITE_BRUSH));
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioCanvas)
rectDraw.SetRect(0, 0, rectDraw.right, (int)(rectDraw.right / nRatioImage));
else if (nRatioImage < nRatioCanvas)
rectDraw.SetRect(0, 0, (int)(rectDraw.bottom * nRatioImage), rectDraw.bottom);
rectDraw.DeflateRect(5, 5);
CSize ptOffset = dest.CenterPoint() - rectDraw.CenterPoint();
rectDraw.OffsetRect(ptOffset);
FrameRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
m_imgPreview.Draw(lpDrawItemStruct->hDC, rectDraw);
}
}
- 我
FillRect
用来擦背景。 - 我使用
CenterPoint
和OffsetRect
制定新的中心。 - 我用来
FrameRect
在图像周围添加一个漂亮的矩形。
推荐阅读
- python - 用python编写的def函数中的加密代码
- python - python-'Status'对象没有属性'lower'
- java - 在混合模式下使用 URI(Windows 和 Linux)
- vba - Excel-vba:使用用户定义函数 (UDF) 获取单元格公式中的选定单元格
- android - 退还用户钱
- docker - 运行 docker-compose up 重建并附加到其他容器
- python - 通过键列表删除嵌套字典中的元素
- vba - 如何下载 Excel 文件的附件?
- azure-active-directory - 使用 Azure Active Directory 对网站进行加密操作时出错
- gantt-chart - 如何在 AnyChart Gantt Resource 中实现假期和工作日