#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 |