바탕화면 윈도우 왼쪽 위 모서리(300 * 300) 을 캡쳐하여 뷰 윈도우 화면에 출력한다.  이 때 200 * 200 사이즈는 흑백으로 변환해서 출력한다. 여기에서 중요한 것은 RGB 컬러를 흑백으로 변환하는 방법이다.
GetRValue() , GetGValue(), GetBValue() 함수는 COLORREF 값에서 RGB 값을 각각 추출하는 매크로이다. 24비트 컬러에서 각각은 8비트이며, RGB 각각에 대해 30, 59,11을 곱한 값을 모두 더해 다시 100으로 나누면 흑백에 해당하는 값을 구할 수 있다. 이 값 하나로 RGB 값을 모두 채우면 RGB 흑백 이미지가 된다. 이 이상의 자료는 이미지 프로세싱 관련 자료를 참고하자.

CWindowDC 는 비클라이언트 영역을 포함한 윈도우 전체에 대한 DC.
따라서 밑의 ScrDC 는 바탕화면 윈도우 전체에 대한 DC를 가진다.



void CSaveGrayDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
 
 CWnd* pWndDesktop = GetDesktopWindow();
 CWindowDC SrcDC(pWndDesktop); //바탕화면 윈도우 DC
 CClientDC dc(this);    //뷰 윈도우 DC

 //바탕 화면 크기 및 색상수와 동일한 비트맵 이미지를 만든다.
 CImage Image;
 Image.Create(300,300,SrcDC.GetDeviceCaps(BITSPIXEL)); //DC의 각종 정보를 추출한다.
// 인자로 전달받은 인덱스에 따라 각각 다른 값을 int형으로 반환하는데 여기에서는 한 픽셀을 표시하는데
// 필요한 비트 수인 32비트(트루를 반환할 것임. 
// 4번째 인자(dwFlags)은 0을 기본값으로 갖고, 32비트 비트맵일 경우 알파 채널을 명시한다.
// 세 번째 인자(nBPP) 가 반드시 32가 되어야 알파 채널을 명시할 수 있다.
// GetDeviceCaps 의 인자인 인덱스에는 BITPIXEL 말고도 HORZSIZE, VERTSIZE 등 (모니터의 물리적 크기 mm)
// 대략 40가지 정도가 더 있는데, 경우에 따라 반환 값의 종류도 다시 검사해서 정보를 판단해야한다.
// 상세한 내용은 MSDN을 참고하자.
 
 // 이미지 DC 와 화면 DC 에 바탕 화면 윈도우 DC 를 출력한다.
 CDC* pDC = CDC::FromHandle(Image.GetDC()); //바탕 화면 윈도우 DC를 가져온다.
 pDC->BitBlt(0,0,300,300, &SrcDC, 0,0, SRCCOPY); // 이미지 DC 에 화면 DC(바탕화면) 내용을 뿌린다.
 Image.ReleaseDC(); //DC를 풀어주고

 // 200,200 만큼 흑백 이미지로 변환
 COLORREF rgb;
 for(int x=0; x<200; x++)
 {
  for(int y=0; y<200; ++y)
  {
   // 바탕화면 각 픽셀을 하나씩 가져와서 rgb에 대입, 이 때 비트맵 이미지를 2차원 배열로 가정하였다.
   rgb = Image.GetPixel(x,y); 
   // GRAY RGB 값으로 변환한다.
   RGBtoGray(rgb);

   Image.SetPixel(x,y,rgb);
  }
 }
 Image.BitBlt(dc.m_hDC, 0,0); //바탕화면 이미지(Image)를 화면 DC(dc.m_hDC)에 0,0에 뿌린다.

 CView::OnLButtonDown(nFlags, point);
}



다음 코드는 마우스 오른쪽 버튼을 눌렀을 때 바탕 화면 모든 영역을 캡쳐해서 저장한 후, 이미지 뷰어로 실행하여 보여준다.

void CSaveGrayDemoView::OnRButtonDown(UINT nFlags, CPoint point)
{
 // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

 CWnd* pWndDesktop = GetDesktopWindow();
 CWindowDC SrcDC(pWndDesktop); //바탕화면 윈도우
 CClientDC dc(this);    //뷰 윈도우

 // 바탕 화면 크기를 알아낸다.
 CRect Rect;
 pWndDesktop->GetWindowRect(&Rect);

 // 바탕 화면 크기 및 색상 수와 동일한 비트맵 이미지를 만든다.
 CImage Image;
 Image.Create(Rect.Width(), Rect.Height(), SrcDC.GetDeviceCaps(BITSPIXEL) );
 
 // 이미지 DC 와 화면 DC에 바탕화면 윈도우 화면을 출력한다.
 CDC* pDC = CDC::FromHandle(Image.GetDC()); //바탕화면 이미지 DC
 pDC->BitBlt(0,0,Rect.Width(), Rect.Height(), &SrcDC, 0, 0,SRCCOPY);
 Image.ReleaseDC();

 //JPEG 형식으로 바탕 화면 이미지를 저장한다.
 Image.Save(_T("DeskTop.jpg"), Gdiplus::ImageFormatJPEG);
 // 저장된 이미지를 뷰어로 실행하여 보여준다.
 ::ShellExecute(NULL, _T("OPEN"), _T("DeskTop.jpg"), NULL, NULL, SW_SHOW);
// 윈도우 탐색기에서 해당 파일을 더블 클릭한 것과 완벽하게 일치하는 동작.
// hwnd 인자는 부모 윈도우의 핸들이며, 이 값이 NULL 일 경우 부모 윈도우는 바탕화면이 된다.
// lpOperation 인자에는 함수가 어떤 동작을 할지 명시한다. open 일 경우 lpFile 인자와 연결된 프로세스를 실행하라는 의미
// 여기서 중요한 점은 lpFile 인자로 전달받는 것이 실행 파일이 아닌 경우 레지의 내용을 참조하여 연결 프로그램을 실행
// 만일 lpFile 에 URL을 준다면 웹 브라우저를 실행하여 해당 사이트로 접속을 시도한다. 이외에 explore,edit,find,print ~~
// lpParameters 인자는 lpFile이 실행 파일인 경우 실행 인자를 명시한다.
// lpDirectory 인자는 실행할 프로그램의 현재 폴더 경로를 명시하며 , NULL 일 경우 윈도우 기본 설정을 적용한다.

 

 CView::OnRButtonDown(nFlags, point);
}




'Windows > MFC' 카테고리의 다른 글

ATL, STL, COM 은 무엇인가?  (0) 2011.11.15
GDI 고급  (0) 2011.11.15
CImage 클래스  (0) 2011.11.14
고급 이미지 출력 함수 ( TransparentBlt() , AlphaBlend() )  (0) 2011.11.14
비트맵과 이미지 처리  (0) 2011.11.14

+ Recent posts