Programación General > C++ Builder
Capturar Imagen Videocamara
touch:
Clase para captura de video con webcam , me funciona muy bien
--- Código: Text --- //---------------------------------------------------------------------------/* * 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);}
archivo de cabecera
--- Código: Text --- //--------------------------------------------------------------------------- //#ifndef c_capH//#define c_capH//---------------------------------------------------------------------------#include <vfw.h> // video for windows library class TCap{private: protected: HWND ParentHandle; HWND hwndVideo; CAPDRIVERCAPS CapDrvCaps; // driver capabilities int SelectedDevice; public: TStringList *pStringCapDrivers; int EnumCapDrv(); void Connect (int Selected); void Format (); void Source (); void CaptureFrame (char *FileName); __fastcall TCap(HWND Handle); __fastcall ~TCap(); }; //#endif
ejemplo de funcionamiento:
--- Código: Text --- HWND w; w = capCreateCaptureWindow("Mi Video", WS_CHILD , 1, 1, 320, 240, panelCaptura->Handle, 0); if (!w) throw Exception("No se pudo seleccionar una ventana de captura"); // Se conecta con el primer dispositivo de captura que encuentra bool bRet; for (int iCapDrv=0; iCapDrv<10; iCapDrv++) { bRet = capDriverConnect(w, iCapDrv); if (bRet) break; } if (!bRet) { Timer1->Enabled=false; // Desactivar Reloj throw Exception("Error: no se encontraron dispositivos."); } // Mostramos en el titulo del form el nombre del driver seleccionado char szNombreDrv[256]; /* if ( capDriverGetName(w, szNombreDrv, sizeof(szNombreDrv)) ) Caption = szNombreDrv; */ // 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(w, &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(w, fcb)) throw Exception("callback no instalado"); capPreviewScale(w, false); capPreviewRate(w, 1);
ahora insercion de la funcion fcb que es llamada como el hook
--- Código: Text --- LRESULT CALLBACK fcb(HWND w, LPVIDEOHDR h){ 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; std::auto_ptr<Graphics::TBitmap> bmp(new Graphics::TBitmap); bmp->PixelFormat = pf24bit; bmp->Width = bi.bmiHeader.biWidth; bmp->Height = bi.bmiHeader.biHeight; SetDIBits(bmp->Canvas->Handle, bmp->Handle, 0, bi.bmiHeader.biHeight, h->lpData, &bi, DIB_RGB_COLORS); std::auto_ptr<TJPEGImage> jpg(new TJPEGImage); jpg->CompressionQuality = 50; jpg->Assign(bmp.get()); // aqui esta elobjeto jpg, has con el lo que quieras return TRUE;}
Navegación
[*] Página Anterior
Ir a la versión completa