원문은 http://stackoverflow.com/questions/28997560/opencv-2-4-displaying-a-cvmat-in-mfc 이곳에서 가져 왔으나, 약간의 문제가 있어 수정한다.
cv::resize()
함수는 기본적으로 같은 비율이 아니더라도 이미지 축소/확대를 지원한다.
만일 MFC에서 같은 비율로 축소/확대를 하기원한다면 (사진뷰어 프로그램과 비슷하게) 아래의 코드를 고려하자.
void DrawCvMat(CDC* pDC, cv::Mat& origin, CRect rect) {
CImage mfcImg;
cv::Mat outImg;
cv::flip(origin, outImg, 0);
//흑백이면 채널을3으로
if (outImg.channels() == 1){
cv::cvtColor(outImg, outImg, CV_GRAY2BGR);
}
//이미지의 크기를 rect에 들어가게 수정합니다.
if (outImg.cols != rect.Width() || outImg.rows != rect.Height()){
int newWidth=outImg.cols*(rect.Height() / (double)outImg.rows);
int newHeight = rect.Height();
if (newWidth > rect.Width()){
newWidth = rect.Width();
newHeight = outImg.rows*(rect.Width() / (double)outImg.cols);
}
cv::resize(outImg, outImg, cv::Size(newWidth, newHeight), 0, 0, CV_INTER_NN);
}
mfcImg.Create(outImg.cols, outImg.rows,24 );
BITMAPINFO bitInfo = { {sizeof(BITMAPINFOHEADER),outImg.cols,outImg.rows,1,24},0 };
void* vp = outImg.data;
IplImage* iplimage = nullptr;
if (outImg.cols % 4 != 0 && outImg.isContinuous()){
iplimage = cvCreateImage(outImg.size(), 8, outImg.channels());
outImg.copyTo(cv::cvarrToMat(iplimage));
vp = iplimage->imageData;
}
pDC->SetStretchBltMode(HALFTONE);
StretchDIBits(mfcImg.GetDC(), 0, 0, outImg.cols, outImg.rows, 0, 0, outImg.cols,outImg.rows, vp, &bitInfo, DIB_RGB_COLORS, SRCCOPY);
if (iplimage != nullptr){
cvReleaseImage(&iplimage);
}
mfcImg.BitBlt(*pDC, (rect.Width() - outImg.cols) / 2 + rect.left, (rect.Height() - outImg.rows) / 2 + rect.top);
mfcImg.ReleaseDC();
outImg.release();
}
사용법은 아래와 같다.
void CMFCExample0001View::OnPaint() {
CPaintDC dc(this);
CRect rect;
this->GetClientRect(&rect);
DBBufferingMaker dbm(&dc, rect);
CDC& cdc = dbm.GetDC();
static cv::Mat img1 = cv::imread("a.jpg",0);
static cv::Mat img3 = cv::imread("a.jpg", 1);
CRect rect1 = rect;
rect1.right = rect1.left + rect1.Width() / 2;
DrawCvMat(&cdc, img1, rect1);
CRect rect2 = rect;
rect2.left = rect2.right - rect2.Width() / 2;
DrawCvMat(&cdc, img3, rect2);
dbm.Finalize();
}