[opencv] MFC DC를 이용해 cv::Mat을 출력하기.

spring·2020년 11월 9일
0

원문은 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();
}
profile
Researcher & Developer @ NAVER Corp | Designer @ HONGIK Univ.

0개의 댓글