블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아

카테고리

분류 전체보기 (176)
잡담 (1)
IT 기기-리뷰&뉴스 (7)
리뷰 - 도서 (1)
리뷰 - 영상 (0)
리뷰 - 그림/음악 (1)
내장형 하드웨어 (163)
Total635,284
Today31
Yesterday129
 → 영상 처리 예제 소스
#include<windows.h>
#include<vfw.h>


HBITMAP hBm; 
BITMAPINFO BInfo;
HWND hWnd;
HWND hVfw;
HDC hdc;

// 라이브러리를 추가하는 것을 comment - 수동식
// project setting을 변화시키면 project를 통채로 복사해야 하지만
// #pragama comment를 사용하면 소스만 복사해도 동작한다.
#pragma comment (lib, "vfw32.lib")

LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp);
/* 고정 형식 */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // 메세지 처리 함수
HINSTANCE g_hInst; // instance 전역 변수 선언
LPCTSTR lpszClass = TEXT("VFW32"); // 윈도 클래스 이름 정의

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
  MSG Message; // MSG 구조체 사용
  WNDCLASS WndClass; // WndClass 구조체 사용
  g_hInst = hInstance; // 윈도우 클래스를 등록하는 프로그램의 번호이며 WinMain의 인수로 전달된 hInstance값을 그대로 대입

  /* 윈도우 클래스 정의 */
  WndClass.cbClsExtra = 0// 예약 영역, 사용하지 않을 경우는 0
  WndClass.cbWndExtra = 0;
  WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // HBRUSH 타입으로 형변환
  WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 윈도우가 사용할 마우스 커서지정
  WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 윈도우가 사용할 아이콘 지정
  WndClass.hInstance = hInstance;
  WndClass.lpfnWndProc = WndProc; // 윈도우의 메시지 처리 함수를 지정
  WndClass.lpszClassName = lpszClass; // 윈도우 클래스의 이름을 문자열로 정의 - 여기서는 First라는 문자열을 보내준다.
  WndClass.lpszMenuName = NULL; // 프로그램이 사용할 메뉴를 지정
  WndClass.style = CS_HREDRAW|CS_VREDRAW; // 윈도우가 어떤 형태를 가질 것인가-윈도우의크기가 변할 경우 윈도우를 다시 그린다.
  
  /* 윈도우 클래스 등록 */
  RegisterClass(&WndClass);  // WndClass 구조체의 번지를 전달

  // 메모리 상에 윈도우 생성
  hWnd=CreateWindow(lpszClass, TEXT("Video for Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
  
/* 인자의 의미 -> (윈도우 클래스 이름, 타이틀바에 나타날 문자열-윈도우 네임(클래스 이름과 같게 하려면 lpszClass), 
            윈도우의 형태 지정, 윈도우의 크기와 위치(픽셀단위)-x, y, nWidth, nHeight, 
            부모 윈도우가 있을 경우 부모윈도우의 핸들-hWndParent, 윈도우에서 사용할 메뉴의 핸들-hmenu, 
            프로그램의 핸들 지정-hinst(프로그램이 종료될 때 파괴되지 않은 윈도우를 자동으로 파괴),
            여러개의 윈도우를 만들때 각 윈도우에 고유의 파라미터를 전달하는 특수 목적에 사용-lpvParam)
            */


  /* 화면에 윈도우 표시 */
  ShowWindow(hWnd, nCmdShow); //  CreateWindow 함수가 리턴한 핸들을 이용하여 출력

  /* 사용자로부터의 메시지 처리*/
  while(GetMessage(&Message, NULL, 00)) // 메시지 큐에서 메시지 읽어옴, 
                      // WN_QUIT이면 False 리턴 후 while문을 빠져나간다.
  {
    TranslateMessage(&Message); // 키보드 입력 처리 
                  // 만약 A키를 누르면 A문자가 입력되었다는 메시지를 만들어 낸다.
    DispatchMessage(&Message); // 큐에서 꺼낸 메시지를 WndProc 함수의 iMAssage로 전달
  }
  return (int)Message.wParam; // 메시지 루프 종료 후 이 프로그램을 실행시킨 OS로 리턴
}


// 사용자와 시스템이 보내오는 메시지를 처리
// 운영체제가 호출하는 함수는 CALLBACK 표시, LRESULT = 4byte long
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{  
  switch(iMessage) // 운영체제로부터 들어온 메시지에 대한 처리
  {
    /* 고정 형식 */
    case WM_CREATE:
      hdc = GetDC(hWnd);
      // 320x240으로 캡쳐, 부모 윈도우(hWnd), 
      // 창이 만들어 진다. - 실제 생성되지는 않는다.
      hVfw = capCreateCaptureWindow(TEXT("Video for Window"), WS_CHILD|WS_VISIBLE, 1010320240, hWnd, 0);
      // usb를 통해 연결된 카메라 장치를 찾아 연결해 준다.
      capDriverConnect(hVfw, 0);
      // hVfw, 1ms - 화면에 보이는 속도(Rate)
      capPreviewRate(hVfw, 1);
      // Video 포멧을 확인하고 정보를 넣는다.
      capGetVideoFormat(hVfw, &BInfo, sizeof(BITMAPINFO));
      BInfo.bmiHeader.biWidth = 320;
      BInfo.bmiHeader.biHeight = 240;
      capSetVideoFormat(hVfw, &BInfo, sizeof(BITMAPINFO));
      // 자동으로 라이브러리에서 Emb_Draw()를 호출해 준다.
      capSetCallbackOnFrame(hVfw, Emb_Draw);
      // 화면에 띄운다.(TRUE)
      capPreview(hVfw, TRUE);
      
      return 0;      
    case WM_LBUTTONDOWN:
      return 0;
    case WM_DESTROY: // 운영체제로부터 들어온 메시지에 대한 처리 - 여기서는 윈도우가 파괴되었음을 알린다.
      ReleaseDC(hWnd, hdc);
      PostQuitMessage(0); // WM_QUIT 메시지를 보냄
      return 0;
  }
  // switch 문에서 처리하지 않은 메시지를 처리
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
// HWND, long *
LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
{
  int xPos;
  int yPos;  
  int iCnt=0;
  for(yPos=240;0<yPos;--yPos)
  {
    for(xPos=0;320>xPos;++xPos)
    {      
      //lp->lpData[iCnt+0]=255;
      SetPixel(hdc, xPos+420, yPos+10, RGB(00, lp->lpData[iCnt])); // 블루
      SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
      SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 00)); // 레드
      iCnt = iCnt +3;
    }
  }  
  return 0;
}

 → 실행 결과


 → 아래 함수를 이용하여 캠에서 들어오는 영상을 복제해서 뿌린다.
// HWND, long *
LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
{
  int xPos;
  int yPos;  
  int iCnt=0;
  for(yPos=240;0<yPos;--yPos)
  {
    for(xPos=0;320>xPos;++xPos)
    {      
      //lp->lpData[iCnt+0]=255;
      SetPixel(hdc, xPos+420, yPos+10, RGB(00, lp->lpData[iCnt])); // 블루
      SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
      SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 00)); // 레드
      iCnt = iCnt +3;
    }
  }  

 → COLORREF SetPixel(hdc, nXPos, nYPos, clrref)
 → 위 함수는 화면에 점을 출력하는 함수로 for문을 돌려 영상을 출력(원본 영상의 복사)한다.
 → 출력은 원본을 제외한 3가지로 BLUE, GREEN, RED 의 색상만을 각각 출력해 본다.

// HWND, long *
LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
{
  int xPos;
  int yPos;  
  int iCnt=0;
  DWORD dwRead;

  hFile = CreateFile("116.bmp", GENERIC_READ, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL);
  
  for(yPos=240;0<yPos;--yPos)
  {
    for(xPos=0;320>xPos;++xPos)
    {      
      //lp->lpData[iCnt+0]=255;
      // 영상
      SetPixel(hdc, xPos+420, yPos+10, RGB(lp->lpData[iCnt+2], lp->lpData[iCnt+1], lp->lpData[iCnt]));
      // BMP
      SetPixel(hdc, xPos+10, yPos+250, RGB(buf[(iCnt+54)+2], buf[(iCnt+54)+1], buf[(iCnt+54)]));
      // BMP + 영상
      SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2]+buf[(iCnt+54)+2], lp->lpData[iCnt+1]+buf[(iCnt+54)+1], lp->lpData[iCnt]+buf[(iCnt+54)]));
      // BMP - 영상
      SetPixel(hdc, xPos+10, yPos+490, RGB(lp->lpData[iCnt+2]-buf[(iCnt+54)+2], lp->lpData[iCnt+1]-buf[(iCnt+54)+1], lp->lpData[iCnt]-buf[(iCnt+54)]));
      // BMP * 영상
      SetPixel(hdc, xPos+420, yPos+490, RGB(lp->lpData[iCnt+2]*buf[(iCnt+54)+2], lp->lpData[iCnt+1]*buf[(iCnt+54)+1], lp->lpData[iCnt]*buf[(iCnt+54)])); 
      
      //SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
      //SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 0, 0)); // 레드
      iCnt = iCnt +3;
    }
  }  
  return 0;
}

 → 실행파일

 → 위의 실행 결과는 왼쪽 처음부터 오른쪽으로 각각
 → 원본영상, 복사 영상
 → BMP출력, 영상+BMP
 → 영상-BMP, 영상*BMP
 → 6가지의 출력을 나타낸 것이다.
 
Posted by 동화다아아

댓글을 달아 주세요

  1. 2014.09.04 15:49 leedoosol  댓글주소  수정/삭제  댓글쓰기

    저 사용자지정함수인 callback함수에서 혹시 다른클래스의 멤버변수를 가져다와서 쓰는 방법을 알고계시나요?

최근에 달린 댓글

최근에 받은 트랙백

글 보관함