WebCamStream->Panel Funzt, und wie bekomme ich das in ein Image ?!
-
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "WDMCap.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; // // Global data // PCWDMCapture pcap=NULL; PCSampleCallbackSink pbsink=NULL; CALLBACKINFO cb={0}; long lWidth; long lHeight ; Graphics::TBitmap *Bitmap3 = new Graphics::TBitmap; //Bitmap3->Bpp = 24; //B/itmap3->Width = 500; //Bitmap3->Height = 500; //--------------------------------------------------------------------------- // This function will be called whenever a captured still needs to be // displayed in the preview window. It is called initially within // CopyBitmap() to display the captured still, but it is also called // whenever the main dialog needs to repaint and when we transition // from video capture mode back into still capture mode. // BOOL DisplayCapturedBits(HWND hwndStill,BYTE *pBuffer, BITMAPINFOHEADER *pbih) { // put bits into the preview window with StretchDIBits // RECT rc; ::GetWindowRect( hwndStill, &rc ); long lStillWidth = rc.right - rc.left; long lStillHeight = rc.bottom - rc.top; HDC hdcStill = GetDC( hwndStill ); PAINTSTRUCT ps; BeginPaint(hwndStill, &ps); SetStretchBltMode(hdcStill, COLORONCOLOR); StretchDIBits( hdcStill, 0, 0, lStillWidth, lStillHeight, 0, 0, lWidth, lHeight, pBuffer, (BITMAPINFO*) pbih, DIB_RGB_COLORS, SRCCOPY ); EndPaint(hwndStill, &ps); ReleaseDC( hwndStill, hdcStill ); return TRUE; } //--------------------------------------------------------------------------- // This is the implementation function that writes the captured video // data onto a bitmap on the user's disk. // BOOL CopyBitmap(HWND hwndStill,double dblSampleTime, BYTE * pBuffer, long lBufferSize) { // figure out where to capture to // long m_nCapTimes=1; TCHAR m_szCapDir[MAX_PATH]="C:\\"; // the directory we want to capture to TCHAR m_szSnappedName[MAX_PATH]; BOOL bFileWritten; TCHAR m_ShortName[MAX_PATH]; wsprintf( m_szSnappedName, TEXT("%sStillCap%4.4ld.bmp"), m_szCapDir, m_nCapTimes ); wsprintf( m_ShortName, TEXT("StillCap%4.4ld.bmp"), m_nCapTimes); // write out a BMP file // HANDLE hf = CreateFile( m_szSnappedName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, NULL, NULL ); if( hf == INVALID_HANDLE_VALUE ) return 0; // write out the file header // BITMAPFILEHEADER bfh; memset( &bfh, 0, sizeof( bfh ) ); bfh.bfType = 'MB'; bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEADER ); bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER ); DWORD dwWritten = 0; WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL ); // and the bitmap format // BITMAPINFOHEADER bih; memset( &bih, 0, sizeof( bih ) ); bih.biSize = sizeof( bih ); bih.biWidth = lWidth; bih.biHeight = lHeight; bih.biPlanes = 1; bih.biBitCount = 24; dwWritten = 0; WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL ); // and the bits themselves // dwWritten = 0; WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL ); CloseHandle( hf ); bFileWritten = TRUE; // Display the bitmap bits on the dialog's preview window DisplayCapturedBits(hwndStill,pBuffer, &bih); // Save bitmap header for later use when repainting the window memcpy(&(cb.bih), &bih, sizeof(bih)); return 0; } //--------------------------------------------------------------------------- void FASTCALL DoRenderStream(double dblSampleTime, BYTE * pBuffer, long lBufferSize,long _lWidth,long _lHeight) { lWidth=_lWidth; lHeight=_lHeight; // Since we can't access Windows API functions in this callback, just // copy the bitmap data to a global structure for later reference. cb.dblSampleTime = dblSampleTime; cb.lBufferSize = lBufferSize; // If we haven't yet allocated the data buffer, do it now. // Just allocate what we need to store the new bitmap. if (!cb.pBuffer) cb.pBuffer = new BYTE[lBufferSize]; // Copy the bitmap data into our global buffer if (cb.pBuffer) memcpy(cb.pBuffer, pBuffer, lBufferSize); // Post a message to our application, telling it to come back // and write the saved data to a bitmap file on the user's disk. PostMessage(Form1->Handle, WM_CAPTURE_BITMAP, 0, 0L); } //--------------------------------------------------------------------------- void FASTCALL _OnBufferingDataSink(void* pev) { int ev=(int)&pev; MessageBox(0,"",IntToStr(ev).c_str(),0); if(1==ev) Form1->Caption="WDMUtils test program :Buffering data..."; else Form1->Caption="WDMUtils test program"; Form1->Repaint(); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { pcap=CWDMCapture::GetWDMCapClassInstance(Handle,WDM_CAPTURE_STREAM); if(NULL!=pcap) { HRESULT hr; pcap->OnDataBuffering =_OnBufferingDataSink; pbsink=new CSampleCallbackSink(); pbsink->pCallbackSink=DoRenderStream; // Create DirectShow graph and start capturing video hr = pcap->StartVideo(pbsink,Panel1->Handle); if (FAILED (hr)) { pcap->CloseInterfaces(); DestroyWindow(pcap->Handle()); } else { // Don't display the main window until the DirectShow // preview graph has been created. Once video data is // being received and processed, the window will appear // and immediately have useful video data to dispay. // Otherwise, it will be black until video data arrives. ShowWindow(pcap->Handle(), TRUE); } } } //--------------------------------------------------------------------------- void __fastcall TForm1::WndProc( Messages::TMessage &Message ) { switch( Message.Msg ) { case WM_GRAPHNOTIFY: if(NULL!=pcap) { pcap->HandleGraphEvent((WPARAM)Message.WParam,(LPARAM)Message.LParam); } break; case WM_SIZE: if(NULL!=pcap) { pcap->ResizeVideoWindow(); } break; case WM_WINDOWPOSCHANGED: if(NULL!=pcap) { pcap->ChangePreviewState(!(IsIconic(Handle))); } break; case WM_CLOSE: // Hide the main window while the graph is destroyed if(NULL!=pcap) { ShowWindow(pcap->Handle(), SW_HIDE); pcap->CloseInterfaces(); // Stop capturing and release interfaces } break; case WM_DESTROY: PostQuitMessage(0); // Field the message posted by our SampleGrabber callback function. case WM_CAPTURE_BITMAP: /// CopyBitmap(Panel2->Handle,cb.dblSampleTime, cb.pBuffer, cb.lBufferSize); CopyBitmap(Form1->Handle,cb.dblSampleTime, cb.pBuffer, cb.lBufferSize); // Image1->Picture->Bitmap = cb.pBuffer; // Image1->Picture->DefaultHandler(Panel2->DefaultHandler()); // PaintBox1->Canvas->Pixels[ 1 ][ 1 ] = Panel2->; break; } // switch TForm::WndProc( Message ); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { delete pbsink; delete pcap; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { if(!IsIconic(Handle)) // Update the bitmap preview window, if we have // already captured bitmap data DisplayCapturedBits(Panel2->Handle,cb.pBuffer, &(cb.bih)); // DisplayCapturedBits(Image1,cb.pBuffer, &(cb.bih)); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { // Free the memory allocated for our bitmap data buffer if (cb.pBuffer != 0) { delete cb.pBuffer; cb.pBuffer = 0; } } //---------------------------------------------------------------------------das teil kopiert den live webcam stream in ein panel, wie bekomme ich jetzt
die roh daten in ein image ? so das ich mit den pixeln weiter arbeiten kann
bin ihrgend wie zu dumm das umzuschreiben kann zwar den stream von dem ding in welchem format auch immer zb aufs form oder auf ein memo feld laden etc..
bekomme aber trozdem net die einzelnen pixel daten
hilfe !
-
//--------------------------------------------------------------------------- #ifndef WDMCapH #define WDMCapH //--------------------------------------------------------------------------- #define __comcat_h__ // EXCLUDE COMCAT.H AS IT COLLIDES WITH QEDIT.H //--------------------------------------------------------------------------- #include <basetsd.h> #include <malloc.h> #include <dshow.h> #include <qedit.h> #include <uuids.h> #include <amstream.h> #if defined(WIN32) #define FASTCALL __fastcall #define _CLOSURE_ __closure #else #define FASTCALL /*__fastcall*/ #define _CLOSURE_ /*__closure*/ #endif //--------------------------------------------------------------------------- // Application-defined message to notify application's window (hosting output) of filtergraph events #define WM_GRAPHNOTIFY (WM_APP+15) //--------------------------------------------------------------------------- #ifdef _DLL_BUILD_ #define _DLL_EXPOSURE_ __declspec(dllexport) #else #define _DLL_EXPOSURE_ __declspec(dllimport) #endif #ifdef __cpluplus extern "C"{ #endif //--------------------------------------------------------------------------- enum PLAYSTATE {Stopped, Paused, Running, Init}; //--------------------------------------------------------------------------- enum WDM_CAPTURE_TYPE { WDM_CAPTURE_PREVIEW,//Preview in window only WDM_CAPTURE_STREAM, //no preview, render to Memory stream WDM_CAPTURE_PREVIEW_STREAM, //preview and render to Memory stream WDM_CAPTURE_AVIFILE,//no preview, capture to avi file WDM_CAPTURE_PREVIEW_AVIFILE //preview and capture to avifile at the same time }; //--------------------------------------------------------------------------- typedef void FASTCALL (*PNotificationSink)(void*); //--------------------------------------------------------------------------- typedef void FASTCALL (*PCBUFFERCALLBACKSINK)(double,BYTE*,long,long,long); typedef void FASTCALL (*PCDEVICEENUMCALLBACK) (char*); //--------------------------------------------------------------------------- //Buffer sink used when capturing to a stream typedef struct tagSampleRenderSink { PCBUFFERCALLBACKSINK pCallbackSink; }CSampleCallbackSink,*PCSampleCallbackSink; typedef void FASTCALL (*DRAWCALLBACK)(HANDLE); //--------------------------------------------------------------------------- typedef class _DLL_EXPOSURE_ tagWDMCapture { private: HWND ghApp; DWORD g_dwGraphRegister; WDM_CAPTURE_TYPE captype; IVideoWindow * g_pVW; IMediaControl * g_pMC; IMediaEventEx * g_pME; IAMVfwCaptureDialogs *g_pDlg; IGraphBuilder * g_pGraph; IBaseFilter* g_pSrcFilter; ICaptureGraphBuilder2 * g_pCapture; PLAYSTATE g_psCurrent; IConfigAviMux *g_pConfigAviMux; //stream capture stuff IBaseFilter* pGrabberBaseFilter; ISampleGrabber *pSampleGrabber; char* g_Capturefilename; PCSampleCallbackSink g_BufferCallbackSink; tagWDMCapture(WDM_CAPTURE_TYPE=WDM_CAPTURE_PREVIEW); tagWDMCapture(HWND,WDM_CAPTURE_TYPE=WDM_CAPTURE_PREVIEW); protected: void Msg(TCHAR *szFormat, ...); // Remote graph viewing functions #ifdef REGISTER_FILTERGRAPH HRESULT FASTCALL AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister); void FASTCALL RemoveGraphFromRot(DWORD pdwRegister); #endif void FASTCALL RegisterForDevChange(void); void FASTCALL UnregisterForDevChange(void); public: static tagWDMCapture* GetWDMCapClassInstance(WDM_CAPTURE_TYPE=WDM_CAPTURE_PREVIEW); static tagWDMCapture* GetWDMCapClassInstance(HWND,WDM_CAPTURE_TYPE=WDM_CAPTURE_PREVIEW); ~tagWDMCapture(void); HRESULT FASTCALL GetInterfaces(void); /* if capturing to an output file,you can choose to render the file to a MultiMediaStream */ //if ur going to use WDM_CAPTURE_AVIFILE u need to provide a target filename //if u r using WDM_CAPTURE_STREAM then the param is a buffer adress HRESULT FASTCALL StartVideo(void* psink=NULL,HWND hPreview=NULL); HRESULT FASTCALL StopPreview(bool final=true); HRESULT FASTCALL PausePreview(void); HRESULT FASTCALL ResumePreview(void); HRESULT FASTCALL FindCaptureDevice(IBaseFilter ** ppSrcFilter); HRESULT FASTCALL SetupVideoWindow(void); HRESULT FASTCALL ChangePreviewState(int nShow); HRESULT FASTCALL HandleGraphEvent(WPARAM,LPARAM); HRESULT FASTCALL CaptureFilterDlg(void); HRESULT FASTCALL CapturePinDlg(void); const HWND FASTCALL Handle(void)const; void FASTCALL CloseInterfaces(void); void FASTCALL ResizeVideoWindow(void); HRESULT FASTCALL SetFullScreen(BOOL FullScreenMode); void FASTCALL setHandle(HWND); void FASTCALL EnumCapDevices( PCDEVICEENUMCALLBACK pDeviceCallbackFunc); PNotificationSink OnDataBuffering; }CWDMCapture,*PCWDMCapture; //--------------------------------------------------------------------------- #ifdef __cpluplus } #endif //--------------------------------------------------------------------------- #endif
-
hmm doof, immer noch keine lösung gefunden, kann mir eventuell wer weiter helfen wenn ich das kompette projekt zum downloaden mal on stelle?
der webcam stream wird via handle in die panel 1 und 2 geladen, kann den handle auch aufs form oder auf ne memo setzen dann hab ich das bild dort,
nur wie bekomme ich das in ein image feld ? damit ich dann die einzelnen pixel abgreifen kann !?
hat einer ne idee? komme einfach net weiter und bin ratlos
-
Also ich denke, das Problem ist, daß du ein Windows-Handle benötigst, aber gleichzeitig die Eigenschaft Canvas benutzen willst.
Das einzige Control, das dies standardmäßig unterstützt ist TForm.Dann kannst du also das Bild von Form->Canvas abgreifen.
Oder aber du baust dir ein eigenes Control abgeleitet von TCustomControl, da dies sowohl von TWinControl abgeleitet ist als auch die Eigenschaft Canvas besitzt.
Die anderen Controls (Panel, Memo etc.) unterstützen nicht das direkte Auslesen der Pixel.
Du kannst dann Canvas->CopyRect(...) benutzen, um die Daten in ein Image zu kopieren und dann abzuspeichern.
-
wenn ichs jetzt aufs tform lade mach mir mal bitte ein beispiel wie es in das image1 dann geht?!
-
Image1->Width = form->Width; // hier noch passende Breite und Höhe bestimmen Image1->Height = form->Height; // falls Form größer als Web-Stream-Image Rect r = Image1->ClientRect(); Rect r2 = Form1->ClientRect(); Image1->CopyRect(r, Form1->Canvas, r2);Wenn du den letzten Parameter 'r2' veränderst, kannst du den Ausschnitt ändern bzw. das Bild strecken oder stauchen.
-
[C++ Error] Unit2.cpp(24): E2335 Overloaded 'Rect' ambiguous in this context
[C++ Error] Unit2.cpp(24): E2379 Statement missing ;
[C++ Error] Unit2.cpp(25): E2335 Overloaded 'Rect' ambiguous in this context
[C++ Error] Unit2.cpp(25): E2379 Statement missing ;
[C++ Error] Unit2.cpp(27): E2316 'CopyRect' is not a member of 'TImage'
[C++ Error] Unit2.cpp(27): E2451 Undefined symbol 'r'
[C++ Error] Unit2.cpp(27): E2451 Undefined symbol 'r2'bei rec meckert er
-
Image1->Width = Form1->Width; // hier noch passende Breite und Höhe bestimmen
Image1->Height = Form1->Height; // falls Form größer als Web-Stream-Image
TRect r = Image1->ClientRect();
TRect r2 = Form1->ClientRect();
Image1->CopyRect(r, Form1->Canvas, r2);----------------------------------------------------------------
[C++ Error] Unit2.cpp(23): E2314 Call of nonfunction
[C++ Error] Unit2.cpp(24): E2314 Call of nonfunction
[C++ Error] Unit2.cpp(25): E2316 'CopyRect' is not a member of 'TImage'
[C++ Warning] Unit2.cpp(26): W8004 'r2' is assigned a value that is never used
[C++ Warning] Unit2.cpp(26): W8004 'r' is assigned a value that is never used
-
Image1->Width = form->Width; // hier noch passende Breite und Höhe bestimmen Image1->Height = form->Height; // falls Form größer als Web-Stream-Image TRect r = Image1->ClientRect; TRect r2 = Form1->ClientRect; Image1->Canvas->CopyRect(r, Form1->Canvas, r2);Warum schreibst du dein Bitmap nich gleich in das Canvas des Images?
-
geht das mit dem quellcode direct ohne rec ?
-
Ja.
Nimm einfach das ClientRect.
-
funzt hab derzeit nur ne cpu auslastung von ca. 20-35%
mal gucken ob ich die ihrgend wie runter bekomme dasist noch bissel viel
gibts ihrgend wie ne möglichkeit die frame rate der cam runter zu bekomme auf 10fps oder so?
-
eins wurmt mich wenn ich die funktion raus nehme die zur speicherung der datei als bmp raus nehme funzt nix mehr
hab das gefühl das er jedes frame auf hdd speichert und dann wieder ihrgend wie löd oder so?
kann man den teil mit der hdd speicherung net raus nehmen ? weil den brauch ich mal garnicht..
-
http://www.keksohr.de/index.php?menu=projekt-index-cam-mca-25
hab hier mal alles drin, quelltexte komme auch die tage

bei fragen ins gästebuch oder via mail melden,gruß philip