//---------------------------------------------------------------------------
/*
* Copyright (c) Allan Petersen, 2001.
* This is a tutorial for a simple capture system using the win32 api
* for accessing your webcam
*
* (c) Copyright 2001, Allan Petersen
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Allan Petersen not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL ALLAN
* PETERSEN BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT ALLAN PETERSEN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Contact Allan Petersen at <support@allanpetersen.com> or visit
* www.allanpetersen.com
*
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include "c_cap.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
LRESULT CALLBACK fcb(HWND w, LPVIDEOHDR h)
{
// En 'h->lpData' tenemos los datos del fotograma
// antes de ser visualizado. En este ejemplo a 320x240 24bits,
// por lo tanto la información de cada pixel estara del siguiente
// modo BLUE-GREEN-RED.... o sea, 3 bytes por cada pixel
// En 'h->dwBytesUsed' tenemos la cantidad de bytes de la imagen
// Para este ejemplo, como demostración vamos a poner la imagen
// en negativo. Aquí podriamos tanto modificar la imagen antes
// de ser vista o bien comprimir estos datos y enviarlos por la red...
typedef struct {BYTE b,g,r;} PIXEL;
char *DatosDib;
DatosDib=new char[h->dwBytesUsed];
int j=0;
for (DWORD i=0; i<h->dwBytesUsed/3; i++)
{
PIXEL *pixel = &((PIXEL*)h->lpData)[i];
/* pixel->r = ~pixel->r;
pixel->g = ~pixel->g;
pixel->b = ~pixel->b; */
DatosDib[j]=pixel->r; j++;
DatosDib[j]=pixel->g; j++;
DatosDib[j]=pixel->b; j++;
}
// frmTomarFoto->Image1->Assig(h->lpdata);
// devolvemos TRUE para que la función siga capturando mas fotogramas
return TRUE;
}
//---------------------------------------------------------------------------
__fastcall TCap::TCap (HWND Handle)
{
// create video capture window
ParentHandle = Handle;
hwndVideo = capCreateCaptureWindow(
(LPSTR) "0",
WS_CHILD | WS_VISIBLE
,
0, 0, 300, 200,
(HWND) Handle,
(int) 0);
pStringCapDrivers = new TStringList;
SelectedDevice = -1;
}
__fastcall TCap::~TCap ()
{
delete pStringCapDrivers;
capPreview(hwndVideo, FALSE); // end preview
capDriverConnect(hwndVideo, SelectedDevice);
capDriverDisconnect(hwndVideo); // disconnect from driver
}
//---------------------------------------------------------------------------
// enumerate the installed capture drivers
//---------------------------------------------------------------------------
int TCap::EnumCapDrv ()
{
char szDeviceName[80]; // driver name
char szDeviceVersion[80]; // driver version
char str[161]; // concatinated string
int xcap; // counter
xcap = 0;
pStringCapDrivers->Clear ();
do {
if (capGetDriverDescription(xcap, szDeviceName, sizeof(szDeviceName),
szDeviceVersion, sizeof(szDeviceVersion))){
sprintf (str, "%s, %s", szDeviceName, szDeviceVersion);
pStringCapDrivers->AddObject (str, (TObject *)xcap);
}
else {
break;
}
xcap++;
} while (true);
return 0;
}
//---------------------------------------------------------------------------
// connecting to selected device and starts preview
//---------------------------------------------------------------------------
void TCap::Connect (int Selected)
{
CAPSTATUS CapStatus;
int hsize;
// capDlgVideoDisplay(hwndVideo);
// connect to the driver
if (SelectedDevice != -1) {
capPreview (hwndVideo, FALSE);
capDriverConnect(hwndVideo, SelectedDevice);
}
if (!capDriverConnect(hwndVideo, Selected)) {
// ---- Unable to connect to driver
return;
}
// update the driver capabilities
capDriverGetCaps (hwndVideo, sizeof(CAPDRIVERCAPS), &CapDrvCaps);
capDlgVideoFormat(ParentHandle);
// Are there new image dimensions
capGetStatus(hwndVideo, &CapStatus, sizeof(CAPSTATUS));
hsize = GetSystemMetrics(SM_CYMENU);
hsize += GetSystemMetrics(SM_CYCAPTION);
// ---- Rescaling the windows
SetWindowPos(hwndVideo, NULL, 0, 0, CapStatus.uiImageWidth,
CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);
SetWindowPos(ParentHandle, NULL, 0, hsize, CapStatus.uiImageWidth,
CapStatus.uiImageHeight+hsize, SWP_NOZORDER | SWP_NOMOVE);
// Cambiar formato de video a 320x240 24bits de color
// tambien podriamos ponerlo manualmente en esta
// resolución usando la función 'capDlgVideoFormat(w);'
BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = 320;
bi.bmiHeader.biHeight = 240;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biCompression = BI_RGB;
if (!capSetVideoFormat(hwndVideo, &bi, sizeof(bi)))
throw Exception("No se puede cambiar el formato de video");
// Definimos la función que sera
// llamada antes de visualizar cada fotograma
if (!capSetCallbackOnFrame(hwndVideo, fcb))
throw Exception("callback no instalado");
// Previsualizar captura
// set preview rate to 33.3 miliseconds, or 30 FPS
capPreviewRate (hwndVideo, 33.3);
// start preview video
capPreview (hwndVideo, TRUE);
// ---- Remember selected device
SelectedDevice = Selected;
}
//---------------------------------------------------------------------------
// Get access to the video source format box
//---------------------------------------------------------------------------
void TCap::Format ()
{
int hsize;
CAPSTATUS CapStatus;
capDlgVideoFormat(hwndVideo);
// Are there new image dimensions
capGetStatus(hwndVideo, &CapStatus, sizeof(CAPSTATUS));
hsize = GetSystemMetrics(SM_CYMENU);
hsize += GetSystemMetrics(SM_CYCAPTION);
SetWindowPos(ParentHandle, NULL, 0, hsize, CapStatus.uiImageWidth,
CapStatus.uiImageHeight+hsize, SWP_NOZORDER | SWP_NOMOVE);
SetWindowPos(hwndVideo, NULL, 0, 0, CapStatus.uiImageWidth,
CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);
}
//---------------------------------------------------------------------------
// Get access to the video source dialog box
//---------------------------------------------------------------------------
void TCap::Source ()
{
capDlgVideoSource(hwndVideo);
}
//---------------------------------------------------------------------------
// capture a frame and save it
//---------------------------------------------------------------------------
void TCap::CaptureFrame (char *FileName)
{
capFileSaveDIB (hwndVideo, FileName);
}