티스토리 뷰

전공/영상처리

[MFC] Raw 파일 읽기

무한공백 2011. 6. 15. 22:48

Raw 파일은 비트맵 파일이나 기타 파일과는 다르게 영상의 데이터만 들어있고,

따라서, 영상의 가로, 세로 크기를 사용자가 알고 있어야 함.
(모르면...걍...걍...끝난거임..ㅎㄷㄷ)

아래는 Raw 파일을 읽는 뼈대 소스임.

//이미지를 읽어들일 배열 선언
BYTE *Img = new BYTE[Width*Height];
//이미지를 읽음
FileRead("C\\~~~", Width, Height, Img, sizeof(BYTE));
//이미지를 읽는 것은 끝!!! 이제 뿌리는 일만 남음.
//FileRead 함수는 읽기 편하게 만든 템플릿 함수로, 그냥 하나 만들어 놓으면 쓸만함.



//FileRead 함수는 아래와 같음.
template <typename T>
FileRead(CString FilePath, int Width, int Height, T* Mem, int TypeSize)
{
//파일 오픈 및 에러 체크
	FILE *fp;
	int errorno = 0;
	int FileLen = widht * height;
	if( (errorno = _wfopen_s(&fp, FullPath, L"rb") ) )
	{
		AfxMessageBox(L"Read File Open Error 00!");
		return 99999;
	}

	fseek(fp, 0L, SEEK_END);
	long len = ftell(fp);///sizeof(short) - WIDTH*HEIGHT;
	fseek(fp, len-FileLen*TypeSize, SEEK_SET);

	//파일 메모리에 적재 및 읽기 에러 체크
	int ReadCount = fread(LoadMem, TypeSize, FileLen, fp);
	if(ReadCount < FileLen)
	{
		TRACE(L"Read Count : %d \n", ReadCount);
		AfxMessageBox(L"File Read Error 00!");
		return 99998;
	}
	//파일을 메모리에 적재 후 닫는다.
	fclose(fp);

	return 0;
}

위 과정으로 Raw 데이터를 적재하는 과정이 끝남.

이제 화면에 보여주기만 하면 됨. 그런데,,,별거 없지만 여긴 좀 과정이 긴....

일단, MDI 또는 SDI 기반에서 화면에 이미지 출력하기!

화면에 출력하기 위해서 비트맵 헤더 정보를 입혀야 하므로, 비트맵 정보를 만들어줌.

//bitmapInfo 형 포인터를 선언 후 할당
BITMAPINFO *m_pBmpInfo8BitGray = NULL;
if(m_pBmpInfo8BitGray != NULL)
{
	delete [] m_pBmpInfo8BitGray;
	m_pBmpInfo8BitGray = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];
}else

m_pBmpInfo8BitGray = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];

//할당 후 각 항목을 채우는데, 각 항목에 관한 자세한 설명은 나중에 첨부..해야할듯.
m_pBmpInfo8BitGray->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pBmpInfo8BitGray->bmiHeader.biPlanes = 1;
m_pBmpInfo8BitGray->bmiHeader.biCompression = BI_RGB;// 0;
m_pBmpInfo8BitGray->bmiHeader.biWidth = Width; //이미지 가로 크기를 적음.
m_pBmpInfo8BitGray->bmiHeader.biHeight = Height;
m_pBmpInfo8BitGray->bmiHeader.biBitCount = 8;
m_pBmpInfo8BitGray->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo8BitGray->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo8BitGray->bmiHeader.biClrUsed = 256;
m_pBmpInfo8BitGray->bmiHeader.biClrImportant = 0;//SHRT_MAX;
m_pBmpInfo8BitGray->bmiHeader.biSizeImage =m_nHeight * WIDTHBYTES( m_nWidth * 8 );

for(int i = 0; i < 256; i++)
{
	m_pBmpInfo8BitGray->bmiColors[i].rgbBlue	= i;
	m_pBmpInfo8BitGray->bmiColors[i].rgbGreen	= i;
	m_pBmpInfo8BitGray->bmiColors[i].rgbRed		= i;
	m_pBmpInfo8BitGray->bmiColors[i].rgbReserved= 0;
}




좋아! 일단 여기까지 하면 비트맵 헤더도 작성된거임. ㅇㅇ...

이제 진짜 OnDraw에서 화면에 출력만 하면 됨!!

void CMyViewerView::OnDraw(CDC* pDC)
{
	CMyViewerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	//주 화면을 그린다.
                //여기서 m_pViewImg 가 읽어들인 RAW DATA 임.
	if(pDoc->m_pViewImg != NULL)
	{
		int Width = pDoc->m_nWidth;
		int Height = pDoc->m_nHeight;
                                //화면에 출력하기 전에 메모리에 먼저 적재한다. 또한, 비트맵 구조체를 만든다.
		CDC memDC;
		CBitmap bitMap, *pOldBitmap;
		//현재 뿌려야할 pDC와 호환되는 memDC를 메모리에 생성한다.
		memDC.CreateCompatibleDC(pDC);
		bitMap.CreateCompatibleBitmap(pDC, Width, Height);
		pOldBitmap = (CBitmap*)memDC.SelectObject(&bitMap);
		memDC.SelectObject(&bitMap);
		memDC.FillSolidRect(&rect, RGB(255, 255, 255));
                                //이 함수는 설명이 길어서 안적음. 한번 찾아서 읽어보시길.
		SetDIBitsToDevice(
		memDC.GetSafeHdc(),			// Handle to the device context.
		0, 0,						// Specifies the x and y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
		Width, Height,   //가로, 세로를 적는다.
		// Specifies the width and height, in logical units, of the DIB. 
		0, 0,				// Specifies the x and y-coordinate, in logical units, of the lower-left corner of the DIB.
		0,					// Specifies the starting scan line in the DIB.
		Height,	//세로를 적음.	// Specifies the number of DIB scan lines contained in the array pointed to by the lpvBits parameter.
		pDoc->m_pViewImg, pDoc->m_pBmpInfo8BitGray, DIB_RGB_COLORS);
                                //StretchBltMode 설정.
		pDC->SetStretchBltMode(COLORONCOLOR);

		//dc.BitBlt(0, 0, rectLP.right, rectLP.bottom, &memDC,0, 0, SRCCOPY);
		//pDC->StretchBlt(0,0,Width, Height, &memDC, 0, 0, Width, Height, SRCCOPY);
                                //비트맵을 화면에 드디어 출력!
		pDC->BitBlt(0,0,Width, Height, &memDC, 0,0,SRCCOPY);

	}
}


다소 어렵게 느껴질 수 있겠지만 요약하면 다음과 같음.

1. 먼저 Raw 파일을 읽어옴. (반듯이 가로, 세로 크기를 알아야함)
2. Raw 파일에 대한 BitmapInfo를 만들어줌. (화면 출력을 위한 사전 준비)
3. 화면에 RAW파일 출력
  3.1 메모리DC 생성 (CDC memDC)
  3.2 현재 View의 DC와 호환되도록 메모리DC 설정 (memDC.CreateCompatibleDC(pDC))
  3.3 현재 View의 DC와 호환되는 Bitmap 생성 (bitmap.CreateCompatibleBitmap(pDC, Widht, Height))
  3.4 SetDIBitsToDevice를 통해 장치 독립적인 bitmap을 화면에 출력하기 위해 설정.
  3.5 BitBlt를 통해 화면에 영상 출력

이것만 알면 어떤 Raw파일이든 읽어서 뿌릴수 있음!!

'전공 > 영상처리' 카테고리의 다른 글

MedianFilter 소스 코드  (0) 2011.06.15
MFC에서 CxImage 이용하기  (5) 2009.10.12
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함