본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형]심재원_2011.11.24일일보고서

by 알 수 없는 사용자 2011. 11. 25.
728x90
반응형
영상에 80 X 60 비트맵 이미지를 덮어쓰는 경우들에는 비트맵 이미지가 원본과는 다르게 나타납니다. 왜 그런지 아시는 분은 알려 주세요.

                                                                                               <원본 이미지>

●주사방식
주사방식이란 화면의 맨 아랫줄 부터 한줄씩 위로 출력을 하여 전체 화면을 출력하는 방식이다. 다음의 이미지는 이를 나타낸 것이다.

주사방식은 NTSC와 PAL로 나뉜다. NTSC는 우리나라와 미국에서 사용하는 방식이다.
●다음은 수업시간에 작성한 영상처리에 관련된 소스 들이다. 소스안의 주석들로 설명을 대체한다.
//복사 영상에 비트맵 이미지 덮어쓰기
#include
 <windows.h>
#include <vfw.h>

#pragma comment(lib,"vfw32.lib"//수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR); //복사영상을 출력하는 함수
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;  
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
           LPSTR lpszCmdParam,int nCmdShow)
{
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;
  HANDLE  hThread;
  DWORD   ThreadID;
  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,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
    NULL,(HMENU)NULL,hInstance,NULL);
  ShowWindow(hWnd,nCmdShow);

  while(GetMessage(&Message,NULL,0,0))
  {
    TranslateMessage(&Message);
    DispatchMessage(&Message);
  }
  return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
  switch(iMessage)
  {
    case WM_CREATE:
      hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);//3번째 인자 부터(계속)
      //순서대로 설명;왼쪽상단 x좌표,왼쪽 상단 y좌표,가로 픽셀크기,세로 픽셀크기
      capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
      capPreviewRate(hVfw,1);//2번째 인자를 높이면 영상 속도는 느려짐 
      capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      BInfo.bmiHeader.biWidth=320//영상 가로크기
      BInfo.bmiHeader.biHeight=240//영상 세로크기
      capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 Emb_Draw함수가 계속 호출된다
      capPreview(hVfw,TRUE); //FALSE로 바꾸면 최초 영상이 사진으로 나타난다.
      
      g_hdc=GetDC(hWnd);    
      return 0;
    case WM_DESTROY:
      ReleaseDC(hWnd,g_hdc);    
      PostQuitMessage(0);
      return 0;
  }
  return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData[](RGB 값)
{
  unsigned int i;
  unsigned int j;
  unsigned int index=0;
  unsigned char* ucP;
  static unsigned char buf[80*60*3]; //이미지 크기가 80X60 픽셀이고, 한점은 3바이트를 차지함
  HANDLE hFile;
  DWORD dwRead;
  HDC hdc;
    
  hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
              NULL);
  ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
  CloseHandle(hFile);

  ucP=&buf[54];
  
  for(i=240;0<i;--i)
  {
    for(j=0;320>j;++j)
    {
      if((400<=360+j)&&(480>=360+j)&&(140<=i)&&(200>=i)) //영상 안에 일정영역이라면
      {
        SetPixel(g_hdc,360+j,i,RGB(*(ucP+2),*(ucP+1),*ucP)); //비트맵 이미지 출력
        ucP=ucP+3;
      }
      else
      {
        SetPixel(g_hdc,360+j,i,RGB(lp->lpData[index+2],lp->lpData[index+1],lp->lpData[index]));//영상 출력
      }
      index=index+3;
    }
    ucP=ucP+(*(LONG*)(&buf[18]))%4;
  }
  

  return 0;
}

 //원본 영상에 비트맵 이미지 덮어쓰기
//중복되는 코드는 생략

LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
  unsigned int i;
  unsigned int j;
  unsigned int index=0;
  unsigned char* ucP;
  static unsigned char buf[80*60*3];
  HANDLE hFile;
  DWORD dwRead;
  HDC hdc;
    
  hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
              NULL);
  ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
  CloseHandle(hFile);

  ucP=&buf[54];
  
  for(i=240;0<i;--i)
  {
    for(j=0;320>j;++j)
    {
      if((40<=j)&&(120>=j)&&(140<=i)&&(200>=i))//원본영상의 특정영역 이라면
      {
        lp->lpData[index+2]=*(ucP+2); //원본영상의 점을 비트맵 점으로 대치함
        lp->lpData[index+1]=*(ucP+1);
        lp->lpData[index]=*ucP;
        ucP=ucP+3;
      }
      
      index=index+3;
    }
    ucP=ucP+(*(LONG*)(&buf[18]))%4;
  }
  

  return 0;
}

Emb_Draw() 함수가 호출되고, 그 다음에 원본영상이 출력이 되므로, Emb_Draw()함수에서 원본영상의 점을 바꿔 버리면 원본영상에는 바뀌어진 점이 출력 되는 것이다. 그러므로, 원본영상에 비트맵 이미지를 덮어쓰는 것이 가능한 것이다.

//원본영상내 비트맵 이미지 키보드로 위치 조작하기
#include
 <windows.h>
#include <vfw.h>

#pragma comment(lib,"vfw32.lib"//수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD WINAPI Thread_Func(LPVOID);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;  
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;
unsigned int uiStartX=40//비트맵 맨 좌측 X좌표
unsigned int uiEndX=120//비트맵 맨 우측 X좌표
unsigned int uiStartY=140//비트맵 맨 위측 Y좌표
unsigned int uiEndY=200//비트맵 맨 아래측 Y좌표

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
           LPSTR lpszCmdParam,int nCmdShow)
{
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;
  HANDLE  hThread;
  DWORD   ThreadID;
  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,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
    NULL,(HMENU)NULL,hInstance,NULL);
  ShowWindow(hWnd,nCmdShow);
  
  

  while(GetMessage(&Message,NULL,0,0))
  {
    TranslateMessage(&Message);
    DispatchMessage(&Message);
  }
  return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
  switch(iMessage)
  {
    case WM_CREATE:
      hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);// 
      capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
      capPreviewRate(hVfw,1);
      capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      BInfo.bmiHeader.biWidth=320;
      BInfo.bmiHeader.biHeight=240;
      capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 이함수가 계속 호출된다
      capPreview(hVfw,TRUE);
                
      return 0;
    case WM_KEYDOWN:
      switch(wParam)
      {
        case VK_LEFT:
          if(0!=uiStartX) //영상 맨 좌측에 이미지가 닿으면 이동 안함
          {
            --uiStartX;
            --uiEndX;
          }
          break;
        case VK_RIGHT:
          if(319-80>uiStartX)//영상 맨 우측에 이미지가 닿으면 이동 안함
          {
            ++uiStartX;
            ++uiEndX;
          }
          break;
        case VK_UP:
          if(1!=uiStartY)//영상 맨 위측에 이미지가 닿으면 이동 안함
          {
            --uiStartY;
            --uiEndY;
          }
          break;
        case VK_DOWN:
          if(240!=uiEndY)//영상 맨 아래측에 이미지가 닿으면 이동 안함
          {
            ++uiStartY;
            ++uiEndY;
          }
          break;
      }
      return 0;
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
  }
  return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
  unsigned int i;
  unsigned int j;
  unsigned int index=0;
  unsigned char* ucP;
  static unsigned char buf[80*60*3];
  HANDLE hFile;
  DWORD dwRead;

    
  hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
              NULL);
  ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
  CloseHandle(hFile);

  ucP=&buf[54];
  
  for(i=240;0<i;--i)
  {
    for(j=0;320>j;++j)
    {
      if((uiStartX<=j)&&(uiEndX>=j)&&(uiStartY<=i)&&(uiEndY>=i)) //방향키를 누르면 전역변수의 값이(계속)
      {                                                          //바뀌므로, 영상내 특정 영역의 위치가 이동함
        lp->lpData[index+2]=*(ucP+2);
        lp->lpData[index+1]=*(ucP+1);
        lp->lpData[index]=*ucP;
        ucP=ucP+3;
      }
      index=index+3;
    }
    ucP=ucP+(*(LONG*)(&buf[18]))%4;
  }
  

  return 0;
}

//원본 영상에 있는 비트맵 이미지 마우스로 위치 조작하기
#include
 <windows.h>
#include <vfw.h>

#pragma comment(lib,"vfw32.lib"//수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;




LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD WINAPI Thread_Func(LPVOID);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;  
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;
unsigned char temp;
unsigned int uiStartX=40;
unsigned int uiEndX=120;
unsigned int uiStartY=140;
unsigned int uiEndY=200;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
           LPSTR lpszCmdParam,int nCmdShow)
{
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;
  HANDLE  hThread;
  DWORD   ThreadID;
  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,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
    NULL,(HMENU)NULL,hInstance,NULL);
  ShowWindow(hWnd,nCmdShow);
  
  

  while(GetMessage(&Message,NULL,0,0))
  {
    TranslateMessage(&Message);
    DispatchMessage(&Message);
  }
  return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
  static BOOL bLbuttonDown=FALSE;
  static int x;
  static int y;
  int current_x;
  int current_y;
  
  switch(iMessage)
  {
    case WM_CREATE:
      hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);// 
      capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
      capPreviewRate(hVfw,1);
      capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      BInfo.bmiHeader.biWidth=320;
      BInfo.bmiHeader.biHeight=240;
      capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
      capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 이함수가 계속 호출된다
      capPreview(hVfw,TRUE);
      return 0;
    case WM_LBUTTONDOWN:
      x=LOWORD(lParam);
      y=HIWORD(lParam);
      bLbuttonDown=TRUE;
      return 0;
    case WM_MOUSEMOVE:
      if(TRUE==bLbuttonDown)
      {
        current_x=LOWORD(lParam);
        current_y=HIWORD(lParam);

        if(0>x-current_x)//마우스 오른쪽 이동
        {
          ++uiStartX;
          ++uiEndX;
        }
        else if(0<x-current_x) //마우스 왼쪽 이동
        {
          --uiStartX;
          --uiEndX;
        }

        if(0>y-current_y) //마우스 아래 이동
        {
          ++uiStartY;
          ++uiEndY;
        }
        else if(0<y-current_y) //마우스 위로 이동
        {
          --uiStartY;
          --uiEndY;
        }
        x=current_x;
        y=current_y;
      }
      return 0;
    case WM_LBUTTONUP:
      bLbuttonDown=FALSE;
      return 0;
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
  }
  return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
  unsigned int i;
  unsigned int j;
  unsigned int index=0;
  unsigned char* ucP;
  static unsigned char buf[80*60*3];
  HANDLE hFile;
  DWORD dwRead;

    
  hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
              NULL);
  ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
  CloseHandle(hFile);

  ucP=&buf[54];
  
  for(i=240;0<i;--i)
  {
    for(j=0;320>j;++j)
    {
      if((uiStartX<=j)&&(uiEndX>=j)&&(uiStartY<=i)&&(uiEndY>=i))
      {
        lp->lpData[index+2]=*(ucP+2);
        lp->lpData[index+1]=*(ucP+1);
        lp->lpData[index]=*ucP;
        ucP=ucP+3;
      }
      index=index+3;
    }
    ucP=ucP+(*(LONG*)(&buf[18]))%4;
  }
  

  return 0;
}
 
 

728x90