영상 캡쳐

영상처리 2010. 6. 8. 17:03



#include<Windows.h>
#include"vfw.h"
#include <math.h>
#include <iostream>

#pragma comment(lib, "vfw32.lib") //vfw32 라이브러리 포함

 


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK FramInfo(HWND, LPVIDEOHDR); // 콜백 함수

TCHAR str[10];    //정수데이터값 확인을 위한 버퍼
unsigned char Menuflag;  //인터페이스 선택

HINSTANCE g_hInst;
HWND hWndMain;
HWND hVFW;
HWND Hwndmain;
HBITMAP hBit;
BITMAPINFO Bm;    //비트맵 정보를 가짐

 

int height, width,red, green, blue;

BYTE *imageData;
BITMAPFILEHEADER *bmfh;

LPVIDEOHDR S_VideoHdr;


//영상 메모리
int TempPos=0;       //스크롤바에 의한 변화값
int grayimage[240][320];    //그레이영상
int hueimage[240][320][3];    //hue 영상
int resultimage[240][320];    //영상처리결과영상


LPCTSTR lpszClass = TEXT("VFW 기본 예제");


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCndParam, int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst = hInstance;
 
 WndClass.cbClsExtra = 0;
 WndClass.cbWndExtra = 0;
 WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 WndClass.hInstance = hInstance;
 WndClass.lpfnWndProc = WndProc;
 WndClass.lpszClassName = lpszClass;
 WndClass.lpszMenuName = NULL;
 WndClass.style = CS_HREDRAW|CS_VREDRAW;
 
 RegisterClass(&WndClass);
 
 //영상을 보여줄 윈도우 생성
 hWnd = CreateWindow(lpszClass, lpszClass,WS_OVERLAPPEDWINDOW|WS_CAPTION,200,200,
  300+150, 300+150, NULL, (HMENU)NULL, hInstance, NULL);
 
 hWndMain = hWnd;
 ShowWindow(hWnd, SW_SHOW);
 
 while(GetMessage(&Message, 0,0,0))
 {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
 
}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC Hdc;
 FILE *file;
 switch(iMessage)
 {
 case WM_CREATE:
  Hwndmain = hWnd;
  Hdc = GetDC(hWnd);
  //캡쳐된 비디오 영상을 보여줄 윈도우 생성
  hVFW = capCreateCaptureWindow(TEXT("VFW"), WS_CHILD|WS_VISIBLE,0,0,1,1,hWnd,0);
  //(캡쳐될 윈도우 이름 생성, 윈도우 스타일, 시작점x좌표, 시작점y좌표, 넓이, 높이, 부모윈도우 핸들, window ID)
  


  capDriverConnect(hVFW,0);  //캡쳐윈도우와 드라이버 연결(캡쳐윈도우 핸들, 캡쳐드라이버의 인덱스)

  capPreviewRate(hVFW,1);  //프리뷰모드에서 보여질 프레임 속도(rate)설정 0=호출x 1=
  //capPreview(hVFW,TRUE);   //프리뷰모드 사용여부
  capGetVideoFormat(hVFW, &Bm, sizeof(Bm)); //영상복사를 위해 사용, 포맷의 크기를 바이트로 전환
  //(캡쳐윈도우 핸들, bitmapinfo 구조체 포인터, 구조체 크기)
  
  hBit = CreateCompatibleBitmap(Hdc, Bm.bmiHeader.biWidth, Bm.bmiHeader.biHeight);
  //DC에 호환하는 비트맵을 생성하여 반환(dc의 핸들, 비트맵의가로 사이즈, 비트맵의 세로 사이즈)
   
  CreateWindow(TEXT("button"),TEXT("스샷"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,Bm.bmiHeader.biWidth+20,20,100,25,hWnd,(HMENU)0,g_hInst,NULL);

  // 비디오 프레임이 캡쳐되었을 경우 처리하기 위한 함수를 설정해주는 매크로 함수
  if(capSetCallbackOnFrame(hVFW, FramInfo)==FALSE)
   //(캡쳐 윈도우 핸들, 콜백함수에 의해 호출되는 함수 포인터)
  {
   return FALSE;
  }
  ReleaseDC(hWnd, Hdc);
  return 0;
 case WM_COMMAND:  //버튼 클릭시
  switch(LOWORD(wParam)){
   case 0:
    WORD wTEMP;
    DWORD dTEMP;

   

    file = fopen("new.bmp","wb");
 
    imageData = (BYTE *)malloc((Bm.bmiHeader.biHeight*Bm.bmiHeader.biWidth)*3);
    bmfh = (BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER));


    wTEMP = 0x4D42;
    bmfh->bfType = wTEMP;
    dTEMP = (Bm.bmiHeader.biHeight*Bm.bmiHeader.biWidth)*3+54;
    bmfh->bfSize = dTEMP;
    wTEMP = 0x0000;
    bmfh->bfReserved1 = wTEMP;
    bmfh->bfReserved2 = wTEMP;
    dTEMP = 54;
    bmfh->bfOffBits = dTEMP;

    int Jump=0;
    for(int iCntY=0; iCntY<Bm.bmiHeader.biHeight; iCntY++)  //캡쳐 영상사이즈만큼
    {
     for(int iCntX=0; iCntX<Bm.bmiHeader.biWidth; iCntX++)
     {
      // 캡쳐영상의 색상값
      red = S_VideoHdr->lpData[Jump+2];
      green = S_VideoHdr->lpData[Jump+1];
      blue = S_VideoHdr->lpData[Jump];
      
      // 캡쳐 영상 출력
      *(imageData+Jump+2)=red;
      *(imageData+Jump+1)=green;
      *(imageData+Jump)=blue;
      Jump+=3;   //3화소
     }
    }

    fwrite(bmfh, sizeof(BITMAPFILEHEADER), 1, file);
    fwrite(&(Bm.bmiHeader),sizeof(BITMAPINFOHEADER),1,file);
    fwrite(imageData,sizeof(BYTE),bmfh->bfSize-54,file);

    return 0;
  }
  return 0;
 case WM_DESTROY:
  free(imageData);
  PostQuitMessage(0);
  return 0;
 }
 return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}


LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr)
{
 HDC Hdc;
 HDC hMemDC;    //메모리DC
 HBITMAP OldBitmap;
 static int first=0;
 int height, width,red, green, blue; //비트맵 영상 정보
 int iCntX, iCntY, Jump;    //영상출력을 위한 변수
 capPreviewRate(hVFW, 0);   //프리뷰모드에서 보여질 프레임 속도를 0으로 설정함
 // 즉 어떠한 처리가 다 끝나기 전에는 다시 콜백함수가 호출되게 하지 않는다
 
 
 height = Bm.bmiHeader.biHeight;  //캡쳐영상의 세로
 width = Bm.bmiHeader.biWidth;  //캡쳐영상의 가로
 
 Hdc=GetDC(Hwndmain);
 hMemDC = CreateCompatibleDC(Hdc);
 OldBitmap = (HBITMAP)SelectObject(hMemDC,hBit);
 
 if(first==0){
  MoveWindow(hWndMain,200,200,width+150,height,true);
  first++;
 }
 
 // 색상값 구하기
 Jump = 0;
 for(iCntY=0; iCntY<height; iCntY++)  //캡쳐 영상사이즈만큼
 {
  for(iCntX=0; iCntX<width; iCntX++)
  {
   // 캡쳐영상의 색상값
   red = VideoHdr->lpData[Jump+2];
   green = VideoHdr->lpData[Jump+1];
   blue = VideoHdr->lpData[Jump];
   
   // 캡쳐 영상 출력
   SetPixel(hMemDC, iCntX, (Bm.bmiHeader.biHeight -iCntY)-1, RGB(red,green,blue));
   Jump+=3;   //3화소
  }
 }
 /*
 BitBlt( Hdc
  ,0 ,0
  ,Bm.bmiHeader.biWidth
  ,Bm.bmiHeader.biHeight
  ,hMemDC
  ,0 ,0
  ,SRCCOPY);*/

 //영상 출력
 SetDIBitsToDevice(Hdc,0,0,width,height,NULL,NULL,NULL,height,VideoHdr->lpData,&Bm,DIB_RGB_COLORS);
// BITMAPINFO itm;


 S_VideoHdr = VideoHdr;

 SelectObject(hMemDC, OldBitmap);
 DeleteDC(hMemDC);
 ReleaseDC(Hwndmain, Hdc);
 capPreviewRate(hVFW, 1); //다음 프레임에는 다시 영상처리를 시작 하게 된다.
 return 0;
}

 

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

SM_BMP.H  (0) 2010.06.16
영상처리 예제1-1  (0) 2010.06.07
영상처리 기본 소스  (0) 2010.06.07
Posted by 지화명이
,