DEV-Language/C++2009. 1. 21. 21:01

비트맵 파일(.bmp)을 표시하게 하려면 GDI 오브젝트의 CBitmap을 사용합니다.

이 작업은 그렇게 간단하지 않습니다. 미리 준비해 놓을 필요가 있습니다.

여기에서는 비트맵(등의) 파일 표시방법을 설명하겠습니다.

 

1. 비트맵 표시용 디바이스 컨텍스트를 준비

비트맵 리소스를 표시할 때 어떤 함수 안에서 실행합니다. 예를 들어 표준적으로는

OnDraw 함수를 사용하지만 이 함수는,

 

void cBitMapView::OnDraw(CDC* pDC)

{

 

}

 

같은 형태로 되어 있습니다. 여기에서 인수 pDC는 ,    디스플레이 표시용 디바이스 컨텍스트

입니다. 문자열인 경우 이 'pDC'에 직접 출력할 수가 있습니다. 그러나 비트맵 리소스일 경우에는

읽어들인 그대로의 파일(단순한 바이트 데이터로 되어있는)을,  어딘가에서 바르게 비트맵 데이터로 전개해 줄 필요가 있습니다. 이를 위해 메모리 상에서 비트맵용 디바이스 컨텍스트를 준비합니다. 이것을 메모리 디바이스 컨텍스트라고 합니다.

 

CDC memDC;                        // 비트맵 표시용 메모리 DC 준비

 

이 디바이스 컨텍스트는 pDC에 올바르게 반영되어야 합니다. 이를 위해

 

memDC.CreateCompatibleDC(pDC);

 

라고 하는 멤버 함수를 사용합니다. 이것은 pDC와 똑 같은 기능의 DC를 작성한다는 의미입니다. 이것은 DC라고는 해도 그 실체는 메모리 상에서 가상으로 만들어져 있는 것입니다. 이처럼

메모리 DC는 화면 이미지를 가상으로 표현하는 메모리 상의 영역, 이라고 생각할 수 있습니다.

메모리 DC는 실제로 디스플레이 화면에서 복사하기 위한 이미지를 미리 메모리에 준비하는 목적으로 사용합니다.

 

2. 비트맵 리소스를 읽어들임

  비트맵 리소스를 읽어들일 때에는 필요한 오브젝트를 준비하여 LoadBitmap 멤버 함수를 사용합니다.

 

CBitmap myBMP;                                              //비트맵 처리용 오브젝트 준비

myBMP.LoadBitmap(IDB_BITMAP_RENGA);         //이미지를 읽어들임

위에서 든 예는 IDB_BITMAP_RENGA라는 ID를 갖는 비트맵 리소스를 읽어들여 myBMP 오브젝트에 집어넣으라는 의미입니다.

 

3.CBitmap 오브젝트의 연결

CPen의 경우와 같이 어떤 CBitmap 오브젝트를 사용할 것인지를 DC에 연결시켜 줍니다.

현재 오브젝트를 저장해 놓고 나중에 복귀할 때도 마찬가지로 필요합니다.

 

CBitmap* oldBitmap= memDC.SelectObject(&myBMP);   // 이전의 비트맵 저장과 myBMP 선택

memDC.SelectObject(oldBMP);                                  // 원래의 비트맵으로 되돌린다.

 

이 memDC.SelectObject(&myBMP); 코드는, myBMP오브젝트의 데이터를 메모리 DC에 출력한다라는 의미를 갖습니다.

 

4. 비트맵 이미지 전송

메모리에 출력된 이미지를 디스플레이에 전송하면 눈에 보이는 이미지가 됩니다.

이것은 BitBit맴버 함수를 사용합니다.

 

pDC->BitBit(10,10,60,100,&memDC,0,0,SRCCOPY);      //비트맵을 전송한다

 

이 코드는(파라미터를 왼쪽에서부터 나타낸다)

  X=10,Y=10이라는 위치에서 가로로 60, 세로로 100(논리단위)이라는 사각형 영역에

  memDC에서 나타내는 전송하기 전의 비트맵의

  좌측 상단 X=0,Y=0의 위치를 기준점으로 하는 이미지를(즉 이미지 전체)그대로

  복사(SRCCOPY)한다.

라는 의미 입니다. 전송방법은 복사(SRCCOPY) 이외에 검정색으로 (BLACKNESS),

반전표(DSTINVERT)등이 있습니다.

 

위 내용은 영진 출판사의 비주얼 c++6 입문(기초편)에 수록된 내용입니다.

 

비트맵 파일을 읽는게 아니라 memDC에 비트맵을 생성하는건 소스를 봅시다.

void CTestView::OnDraw(CDC* pDC)
{
   CTestDoc* pDoc = GetDocument();                              //DOC와 연결
   CMainFrame* pframe = (CMainFrame*)GetParentFrame(); // MainFrame과 연결

 

   // -------------------------------------------------------------------
   // 1. 오버레이를 위한 내용

   // -------------------------------------------------------------------
 
CDC memDC;   // 비트맵 출력용 메모리 dc생성

 

  memDC.CreateCompatibleDC(pDC); 

  // 메모리dc를 클라이언트 pDC와 호완성 가지게 함
  // CreateCompatibleDC(); 는 pDC와 똑같은 DC를 작성한다는 의미
  // 이것은 DC라고는 해도 그 실체는 메모리상에 가상으로 만들어져 있는 것입니다.
 

  CBitmap bmpTemp;   // 비트맵 처리용 오브젝트
  CBitmap* pOldBmp;  // 이전의 비트맵
  bmpTemp.CreateCompatibleBitmap(

        pDC,                  // pDC에

        biWidth,              // 비트맵의 가로 사이즈

        biHeight              // 비트맵의 세로 사이즈

        );                      // 비트맵생성
  pOldBmp = (CBitmap*)memDC.SelectObject(&bmpTemp
); 

  // 메모리DC에 비트맵 연결

 

   if( pframe->m_bFullScreenViewingMode ) 

     // bool m_bFullScreenViewingMode가 true면 전체화면 모드이면

     // 이미지를 사이즈를 조정하여 출력한다.
   {
      int nScreenWidth  = ::GetSystemMetrics( SM_CXSCREEN ); 

      // 화면의 x값 얻어옴
      int nScreenHeight = ::GetSystemMetrics( SM_CYSCREEN ); 

      // 화면의 y값 얻어옴

      pframe->SetWindowPos(

                     NULL,

                     0,
                     0,
                     nScreenWidth,
                     nScreenHeight,
                     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); 

                     // 윈도우 설정

 

 

      ::StretchDIBits(

            pDC->GetSafeHdc(), // 출력 DC
            0,                          // 출력 DC의 시작점 X
            0,                          // 출력 DC의 시작점 Y
            nScreenWidth,          // 출력 DC에서의 가로 크기
            nScreenHeight,         // 출력 DC에서의 세로 크기
            0,           // DIB의 시작점 X, x-coord of source upper-left corner
            0,           // DIB의 시작점 Y, y-coord of source upper-left corner
            pDoc->m_bitmapInfo.bmiHeader.biWidth, // DIB의 가로 크기
            ::abs( pDoc->m_bitmapInfo.bmiHeader.biHeight ), // DIB의 세로 크기
            pDoc->m_imageProcessed.pData, // DIB 정보 버퍼
           &pDoc->m_bitmapInfo,                 // BITMAPINFO 정보 구조체
           DIB_RGB_COLORS,
                          // 팔레트 정보
           SRCCOPY                                // ROP 코드 
           );
 

          // DIB를 출력할 경우에 사용하는 대표적인 함수

             (비트맵 정보를 확대 또는 축소하여 출력)
      
   }
   else // bool m_bFullScreenViewingMode가 false면
   {
      
// draw the bitmap to the screen.
      if( ::SetDIBitsToDevice(

              memDC.GetSafeHdc(), // pDC가 아닌 메모리 DC에 영상저장
                                            //pDC->GetSafeHdc(), // 출력할 DC 핸들
              0,                           // 출력할 DC의 시작 X 좌표
              0,                           // 출력할 DC의 시작 Y 좌표 
              pDoc->m_bitmapInfo.bmiHeader.biWidth,              // DIB의 가로 크기
              ::abs( pDoc->m_bitmapInfo.bmiHeader.biHeight ), // DIB의 세로 크기
              0,                           // DIB의 출력 시작 X 좌표
              0,                           // DIB의 출력 시작 Y 좌표
              0,                           // 첫 번째 출력 라인
              ::abs( pDoc->m_bitmapInfo.bmiHeader.biHeight ), // 총 출력 라인수
              pDoc->m_imageProcessed.pData,  // DIB 정보를 가지고 있는 버퍼
              &pDoc->m_bitmapInfo,                 // BITMAPINFO 정보 구조체
              DIB_RGB_COLORS                      // 팔레트 정보
              )  == 0 ) 

              // DIB를 출력할 경우에 사용하는 대표적인 함수

              //(비트맵 정보를 그대로 DC에 출력)
      {
         // error.
      }
   

    // ---------------------------------------------------------------------

    // 3. 오버레이 테스트, 메모리 DC Free

    // ----------------------------------------------------------------------      pDC->BitBlt(

                      0,

                      0,

                      pDoc->m_bitmapInfo.bmiHeader.biWidth,

                      ::abs( pDoc->m_bitmapInfo.bmiHeader.biHeight),
                      &memDC, 0, 0, SRCCOPY);

      //메모리 DC에 있는 내용을 pDC로 출력한다.
   }

   memDC.SelectObject( pOldBmp ); //메모리 DC Free
   bmpTemp.DeleteObject();
   memDC.DeleteDC();

 

 

 

 

 

 

[출처] 비트맵 표시방법.|작성자 세훈


Posted by 몽센트