[Vision] View Manager Class - 뷰 관리자 클래스
Posted on 2008/05/25 22:10
Filed Under Complete project
1. 요 약#
MFC MDI Multi-View, Single-Document 구조로 프로젝트를 진행하면서 ChildWindow 의 인터페이스를 제공하는 클래스를 제작하였습니다.
사실 초기에는 ChildWindow 의 DC에 대한 입출력을 관리하는 목적으로 ViewManager 라고 네이밍을 달았는데 점점 여러가지 인터페이스가 추가되면서 의미가 완전 틀려졌네요. 이름을 짓자면 ChildManager 이 적당할 듯 합니다.
2. 구 현#
[code]/* 2008.04.03 Furyheimdall - View Manager Class */#pragma once
#include "afxwin.h"
#include "../../ChildFrm.h"
#include <cv.h>
#include <highgui.h>
class CViewManager
{
public:
void Init(CFrameWnd*); //객체 초기화 (출력할 윈도우의 핸들)
void IplRegister(IplImage* ptr); //IPL 이미지 데이터 등록
void ReleaseView(); //객체 해제
void ShowImage(CDC* pDC = NULL); //DC에 이미지 출력
void SetImageSize(int mode, int x, int y=NULL); //이미지 출력 비율 변경
void UpdateScreen(); //윈도우 사이즈를 현재 비율에 맞도록 갱신
public:
enum { modeAbsolute , modeRelative };
public:
CChildFrame *IDentity;
CView *View;
IplImage* IplData;
CClientDC* dc;
LPBITMAPINFO BitmapInfo; //CViewOut 객체의 입/출력 비트맵 정보
int m_iWidth; //출력공간 너비
int m_iHeight; //출력공간 높이
int m_RateWidth; //너비 비율
int m_RateHeight; //높이 비율
};[/code]
ViewManager 클래스의 헤더입니다.
기본적으로 afxwin.h 를 포함하고 있으며 ChildFrame 의 헤더를 포함하고 있습니다.
그리고 OpenCV 자료구조를 사용하기 때문에 OpenCV 헤더도 포함합니다.
메소드, 속성정의, 변수(객체) 순으로 선언해놨습니다.
[code]/* 2008.04.03 Furyheimdall - ViewManager Class */
#pragma once
#include "StdAfx.h"
#include "ViewManager.h"
void CViewManager::Init(CFrameWnd* Object) //객체 초기화 (차일드프레임 포인터)
{
//차일드 프레임에서 뷰포인터를 가져오고 차일드 포인터를 복사
View = Object->GetActiveView();
IDentity = dynamic_cast<CChildFrame*>(Object);
//뷰 포인터에서 DC를 가져옴
dc = new CClientDC(View);
m_RateWidth = 100;
m_RateHeight = 100;
m_iHeight = 0;
m_iWidth = 0;
//Bitmap 구조체 초기화
BitmapInfo=NULL;
BitmapInfo = reinterpret_cast<BITMAPINFO*>(new char[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)]);
BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfo->bmiHeader.biPlanes = 1;
BitmapInfo->bmiHeader.biCompression = BI_RGB;
BitmapInfo->bmiHeader.biXPelsPerMeter = 0;
BitmapInfo->bmiHeader.biYPelsPerMeter = 0;
BitmapInfo->bmiHeader.biClrUsed = 256;
BitmapInfo->bmiHeader.biClrImportant = 0;
int i;
for(i=0;i<256;i++)
{
BitmapInfo->bmiColors[i].rgbRed=(UINT8)i;
BitmapInfo->bmiColors[i].rgbGreen=(UINT8)i;
BitmapInfo->bmiColors[i].rgbBlue=(UINT8)i;
BitmapInfo->bmiColors[i].rgbReserved=0;
}
}
void CViewManager::IplRegister(IplImage* ptr)
{
IplData = ptr;
SetImageSize(CViewManager::modeAbsolute,100);
}
void CViewManager::ReleaseView()
{
delete []BitmapInfo;
dc->DeleteDC();
}
void CViewManager::ShowImage(CDC* pDC) //DC에 이미지 출력
{
/* IplImage 로 부터 비트카운트 계산후 비트맵 헤더 적용 */
BitmapInfo->bmiHeader.biBitCount = IplData->depth * IplData->nChannels;
BitmapInfo->bmiHeader.biWidth = m_iWidth;
BitmapInfo->bmiHeader.biHeight =-m_iHeight;
if(IplData->depth == 24)
BitmapInfo->bmiHeader.biSizeImage = m_iWidth * m_iHeight * 3;
if(IplData->depth == 8)
BitmapInfo->bmiHeader.biSizeImage = m_iWidth * m_iHeight;
/* 리사이즈 이미지 계산 */
IplImage* ResizeImage = cvCreateImage(cvSize(m_iWidth,m_iHeight),IplData->depth,IplData->nChannels);
cvResize(IplData,ResizeImage);
/* 화면에 출력 */
if(pDC == NULL){
View->OnPrepareDC(dc);
::StretchDIBits(dc->GetSafeHdc(),0,0,m_iWidth ,m_iHeight ,0,0,m_iWidth,m_iHeight,ResizeImage->imageData,BitmapInfo,DIB_RGB_COLORS,SRCCOPY);
}
else {
::StretchDIBits(pDC->GetSafeHdc(),0,0,m_iWidth ,m_iHeight ,0,0,m_iWidth,m_iHeight,ResizeImage->imageData,BitmapInfo,DIB_RGB_COLORS,SRCCOPY);
}
cvReleaseImage(&ResizeImage);
}
void CViewManager::SetImageSize(int mode, int x, int y)
{
if(mode == CViewManager::modeRelative){
m_RateHeight += x;
m_RateWidth += y;
}
else if (mode == CViewManager::modeAbsolute) {
m_RateHeight = x;
m_RateWidth = x;
}
m_iHeight = static_cast<int>(IplData->height * (m_RateHeight/100.0));
m_iWidth= static_cast<int>(IplData->width * (m_RateWidth/100.0));
}
void CViewManager::UpdateScreen()
{
CRect r;
IDentity->GetWindowRect(&r);
r.top -= 160; //Main Frame Ribbon Size
r.left -= 5; //Main Frame left boader size
r.right = m_iWidth + r.left + BOADER_SIZE*2;
r.bottom = m_iHeight + r.top + BOADER_SIZE+PANNEL_SIZE;
IDentity->MoveWindow(&r);
View->Invalidate();
}[/code]
Init 에서 ChildFrame 에 대한 포인터를 받아서 View 와 ChildFrame 그리고 DC 를 추출하여 ViewManager 에서 보관하게 됩니다.
그리고 2nd-Phase 생성자라고 볼 수 있는 IplRegister 메소드를 통해 ViewManager 클래스로 생성된 객체에게 자신이 그려야 할 이미지 정보를 넘겨줍니다.
이후 ShowImage() 를 통해 ChildWindow 에 이미지 출력이나 SetImageSize 를 통해 이미지 출력비율, 크기 변경, 그리고 추가적으로 인터페이스를 생성 할 수 있게 됩니다.
3. 문제점#
정리가 되지 않은 코드라 시험적으로 추가했던 흔적들이 많이 남아있습니다.
윈도우 위치, 사이즈 경우는 임의로 직접 픽셀값을 체크하여 정확하게 넣은건데 Windows XP 의 윈도우 크기에 영향을 받더군요.
결국 정확한 윈도우 사이즈를 구하기 위한 코드를 다른 어디에 추가하여 그 값을 기준으로 변경해야 할 듯 합니다.
그리고 전체적인 프로그래밍을 간편하기 위해 직접 OpenCV 자료형을 코드에서 사용하기 때문에 의존적인 클래스가 되었습니다.
'Complete project' 카테고리의 다른 글
| [Vision] Window Manager Class - 윈도우 관리 클래스 (0) | 2008/05/25 |
|---|---|
| [Vision] View Manager Class - 뷰 관리자 클래스 (0) | 2008/05/25 |
| [Vision] MFC Architect - MFC 구조 (0) | 2008/05/25 |
| [Vision] Camera management class - 카메라 관리 클래스 (0) | 2008/04/08 |
| [Vision] Display management class - 화면 출력 관리 클래스 (0) | 2008/04/08 |
| [Vision] Log management class - 로그 관리 클래스 (0) | 2008/03/28 |




댓글을 달아 주세요