WebCam die 2.
-
Hallo,
ich habe vor einigher Zeit mal folgenden Quellcode von Toom bekommen
#include <windows.h> #include <vfw.h> #include "resource.h" #define ID_BUTTON_FOTO 1 #define ID_BUTTON_CLOSE 2 #define ID_VIDEO_WINDOW 3 #define BUTTON_BREITE 60 #define BUTTON_HOHE 20 #define FENSTER_BREITE 350 #define FENSTER_HOHE 320 #define P_FILM 0 #define P_FOTO 1 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL FensterSkalieren (HWND) ; BOOL ButtonsSkalieren (HWND, int, int) ; BOOL BildSpeichern (HWND, PTSTR) ; TCHAR szAppName[] = TEXT ("WebCam") ; OPENFILENAME ofn ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ HWND hwnd ; MSG msg ; WNDCLASSEX wndclassex ; wndclassex.cbSize = sizeof (WNDCLASSEX) ; wndclassex.style = CS_HREDRAW | CS_VREDRAW ; wndclassex.lpfnWndProc = WndProc ; wndclassex.cbClsExtra = 0 ; wndclassex.cbWndExtra = 0 ; wndclassex.hInstance = hInstance ; wndclassex.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (101)) ; wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclassex.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; wndclassex.lpszMenuName = szAppName ; wndclassex.lpszClassName = szAppName ; wndclassex.hIconSm = NULL ; RegisterClassEx (&wndclassex) ; hwnd = CreateWindowEx (NULL , szAppName, TEXT ("WebCam"), WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION, CW_USEDEFAULT , CW_USEDEFAULT , FENSTER_BREITE, FENSTER_HOHE, NULL, LoadMenu (hInstance, MAKEINTRESOURCE (102)), hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HINSTANCE hInstance ; static HWND hwndVideo ; static int iIndex = 0 ; char szDeviceName[80], szDeviceVersion[80], str[161], szFileName[MAX_PATH] ; static int iBreite = 0, iHoche = 0, iPruef = P_FOTO ; switch (message){ case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam) -> hInstance ; CreateWindowEx (NULL, "button", TEXT ("Foto"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU) ID_BUTTON_FOTO, hInstance, NULL) ; CreateWindowEx (NULL, "button", TEXT ("Ende"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU) ID_BUTTON_CLOSE, hInstance, NULL) ; hwndVideo = capCreateCaptureWindow( (LPSTR) "Meine WebCam", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, (HWND) hwnd, (int) ID_VIDEO_WINDOW) ; if (!capDriverConnect (hwndVideo, iIndex)) { MessageBox (hwnd, "Treiber für die Webcam kann nicht geladen werden...", "Fehler", MB_ICONERROR) ; SendMessage (hwnd, WM_DESTROY, 0, 0) ; return 0; } capPreviewRate (hwndVideo, 33.3) ; capPreview (hwndVideo, TRUE) ; capGetDriverDescription (iIndex, szDeviceName, sizeof (szDeviceName), szDeviceVersion, sizeof (szDeviceVersion)) ; wsprintf (str, "%s, %s", szDeviceName, szDeviceVersion) ; MessageBox (NULL, str, "Verbunden über...", NULL) ; FensterSkalieren (hwnd) ; ButtonsSkalieren (hwnd, iBreite, iHoche) ; return 0 ; case WM_SIZE : iBreite = LOWORD (lParam) ; iHoche = HIWORD (lParam) ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)){ case ID_DATEI_BEENDEN : case ID_BUTTON_CLOSE : SendMessage (hwnd, WM_DESTROY, 0, 0) ; break ; case ID_BUTTON_FOTO : if (iPruef == P_FOTO){ SetWindowText (GetDlgItem (hwnd, ID_BUTTON_FOTO), "Film") ; capPreview (hwndVideo, FALSE) ; iPruef = P_FILM ; } else if (iPruef == P_FILM){ SetWindowText (GetDlgItem (hwnd, ID_BUTTON_FOTO), "Foto") ; capPreview (hwndVideo, TRUE) ; iPruef = P_FOTO ; } break ; case ID_DATEI_SPEICHERN : szFileName[0] = '\0' ; BildSpeichern (hwnd, szFileName) ; capFileSaveDIB (hwndVideo, szFileName) ; break ; case ID_BEARBEITEN_QELLE : capDlgVideoSource(hwndVideo) ; break ; case ID_BEARBEITEN_AUFLOESUNG : capDlgVideoFormat (hwndVideo) ; FensterSkalieren (hwnd) ; ButtonsSkalieren (hwnd, iBreite, iHoche) ; break ; case ID_BEARBEITEN_KOMPRESION: capDlgVideoCompression(hwndVideo) ; break ; } return 0 ; case WM_DESTROY : capPreview (hwndVideo, FALSE) ; capDriverDisconnect (hwndVideo) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL BildSpeichern (HWND hParent, PTSTR pstrFileName){ ZeroMemory (&ofn, sizeof (OPENFILENAME)) ; ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hInstance = NULL ; ofn.lpstrFilter = TEXT ("Bilddateiten (*.BMP)\0*.bmp\0") TEXT ("Alle Dateien (*.*)\0*.*\0\0") ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.nMaxFile = MAX_PATH ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0L ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; ofn.hwndOwner = hParent ; ofn.lpstrFile = pstrFileName ; ofn.lpstrFileTitle = NULL ; ofn.Flags = OFN_OVERWRITEPROMPT ; return GetSaveFileName (&ofn) ; } BOOL ButtonsSkalieren (HWND hwndParent, int iBreite, int iHoche){ MoveWindow (GetDlgItem (hwndParent, ID_BUTTON_CLOSE), iBreite - BUTTON_BREITE, iHoche - BUTTON_HOHE, BUTTON_BREITE, BUTTON_HOHE, TRUE) ; MoveWindow (GetDlgItem (hwndParent, ID_BUTTON_FOTO), iBreite - (2 * BUTTON_BREITE) - 5, iHoche - BUTTON_HOHE, BUTTON_BREITE, BUTTON_HOHE, TRUE) ; return TRUE ; } BOOL FensterSkalieren (HWND hParent){ CAPSTATUS CS ; capGetStatus (GetDlgItem (hParent, ID_VIDEO_WINDOW), &CS, sizeof (CAPSTATUS)) ; SetWindowPos (GetDlgItem (hParent, ID_VIDEO_WINDOW), NULL, 0, 0, CS.uiImageWidth, CS.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE) ; SetWindowPos (hParent, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CS.uiImageWidth, CS.uiImageHeight + 75, SWP_NOZORDER | SWP_NOMOVE) ; return TRUE ; } /* du kannst natürlich auch ohne das menue das video sehen... must aber den code bisschen abspaecken (fast die gesammte WM_COMMAND muss raus, bis auf die ID_BUTTON_CLOSE & ID_BUTTON_FOTO). */
Da er aber seine resource.h nicht rausgerückt hat, musste ich den Code entsprechend kürzen.
Nach meiner "BEarbeitung" sieht er so aus.#include <windows.h> #include <vfw.h> //#include "resource.h" #define ID_BUTTON_FOTO 1 #define ID_BUTTON_CLOSE 2 #define ID_VIDEO_WINDOW 3 #define BUTTON_BREITE 60 #define BUTTON_HOHE 20 #define FENSTER_BREITE 350 #define FENSTER_HOHE 320 #define P_FILM 0 #define P_FOTO 1 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL FensterSkalieren (HWND) ; BOOL ButtonsSkalieren (HWND, int, int) ; BOOL BildSpeichern (HWND, PTSTR) ; TCHAR szAppName[] = TEXT ("WebCam") ; OPENFILENAME ofn ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ HWND hwnd ; MSG msg ; WNDCLASSEX wndclassex ; wndclassex.cbSize = sizeof (WNDCLASSEX) ; wndclassex.style = CS_HREDRAW | CS_VREDRAW ; wndclassex.lpfnWndProc = WndProc ; wndclassex.cbClsExtra = 0 ; wndclassex.cbWndExtra = 0 ; wndclassex.hInstance = hInstance ; wndclassex.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (101)) ; wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclassex.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; wndclassex.lpszMenuName = szAppName ; wndclassex.lpszClassName = szAppName ; wndclassex.hIconSm = NULL ; RegisterClassEx (&wndclassex) ; hwnd = CreateWindowEx (NULL , szAppName, TEXT ("WebCam"), WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION, CW_USEDEFAULT , CW_USEDEFAULT , FENSTER_BREITE, FENSTER_HOHE, NULL, LoadMenu (hInstance, MAKEINTRESOURCE (102)), hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HINSTANCE hInstance ; static HWND hwndVideo ; static int iIndex = 0 ; char szDeviceName[80], szDeviceVersion[80], str[161]; szFileName[MAX_PATH] ; static int iBreite = 0, iHoche = 0, iPruef = P_FOTO ; switch (message){ case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam) -> hInstance ; CreateWindowEx (NULL, "button", TEXT ("Foto"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU) ID_BUTTON_FOTO, hInstance, NULL) ; CreateWindowEx (NULL, "button", TEXT ("Ende"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd, (HMENU) ID_BUTTON_CLOSE, hInstance, NULL) ; hwndVideo = capCreateCaptureWindow( (LPSTR) "Meine WebCam", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, (HWND) hwnd, (int) ID_VIDEO_WINDOW) ; if (!capDriverConnect (hwndVideo, iIndex)) { MessageBox (hwnd, "Treiber für die Webcam kann nicht geladen werden...", "Fehler", MB_ICONERROR) ; SendMessage (hwnd, WM_DESTROY, 0, 0) ; return 0; } capPreviewRate (hwndVideo, 33.3) ; capPreview (hwndVideo, TRUE) ; capGetDriverDescription (iIndex, szDeviceName, sizeof (szDeviceName), szDeviceVersion, sizeof (szDeviceVersion)) ; wsprintf (str, "%s, %s", szDeviceName, szDeviceVersion) ; MessageBox (NULL, str, "Verbunden über...", NULL) ; FensterSkalieren (hwnd) ; ButtonsSkalieren (hwnd, iBreite, iHoche) ; return 0 ; case WM_SIZE : iBreite = LOWORD (lParam) ; iHoche = HIWORD (lParam) ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)){ case ID_BUTTON_CLOSE : SendMessage (hwnd, WM_DESTROY, 0, 0) ; break ; case ID_BUTTON_FOTO : if (iPruef == P_FOTO){ SetWindowText (GetDlgItem (hwnd, ID_BUTTON_FOTO), "Film") ; capPreview (hwndVideo, FALSE) ; iPruef = P_FILM ; } else if (iPruef == P_FILM){ SetWindowText (GetDlgItem (hwnd, ID_BUTTON_FOTO), "Foto") ; capPreview (hwndVideo, TRUE) ; iPruef = P_FOTO ; } break ; } return 0 ; case WM_DESTROY : capPreview (hwndVideo, FALSE) ; capDriverDisconnect (hwndVideo) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL BildSpeichern (HWND hParent, PTSTR pstrFileName){ ZeroMemory (&ofn, sizeof (OPENFILENAME)) ; ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hInstance = NULL ; ofn.lpstrFilter = TEXT ("Bilddateiten (*.BMP)\0*.bmp\0") TEXT ("Alle Dateien (*.*)\0*.*\0\0") ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.nMaxFile = MAX_PATH ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0L ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; ofn.hwndOwner = hParent ; ofn.lpstrFile = pstrFileName ; ofn.lpstrFileTitle = NULL ; ofn.Flags = OFN_OVERWRITEPROMPT ; return GetSaveFileName (&ofn) ; } BOOL ButtonsSkalieren (HWND hwndParent, int iBreite, int iHoche){ MoveWindow (GetDlgItem (hwndParent, ID_BUTTON_CLOSE), iBreite - BUTTON_BREITE, iHoche - BUTTON_HOHE, BUTTON_BREITE, BUTTON_HOHE, TRUE) ; MoveWindow (GetDlgItem (hwndParent, ID_BUTTON_FOTO), iBreite - (2 * BUTTON_BREITE) - 5, iHoche - BUTTON_HOHE, BUTTON_BREITE, BUTTON_HOHE, TRUE) ; return TRUE ; } BOOL FensterSkalieren (HWND hParent){ CAPSTATUS CS ; capGetStatus (GetDlgItem (hParent, ID_VIDEO_WINDOW), &CS, sizeof (CAPSTATUS)) ; SetWindowPos (GetDlgItem (hParent, ID_VIDEO_WINDOW), NULL, 0, 0, CS.uiImageWidth, CS.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE) ; SetWindowPos (hParent, NULL, CW_USEDEFAULT, CW_USEDEFAULT, CS.uiImageWidth, CS.uiImageHeight + 75, SWP_NOZORDER | SWP_NOMOVE) ; return TRUE ; }
Allerdings seint da was nicht zu stimmen, da ich beim kompilieren 2 Fehlermeldungen erhalte:
error C2065: 'szFileName' : nichtdeklarierter Bezeichner
error C2109: Index benoetigt ein Feld oder einen ZeigertypKönnt ihr mir weiterhelfen, damit ich die Cam zum laufen bekomme ???
danke!Romeo-G
P.S.: Arbeite mit MS Visual C++
-
Wenn du jetzt noch die Zeilen markieren würdest, in denen die Fehler auftreten, könnte dir geholfen werden.
-
Also, di komplette Fehlermeldung sieht so aus:
--------------------Konfiguration: Cam_Einbindung_v01 - Win32 Debug--------------------
Kompilierung läuft...
main.cpp
D:\Schule\Schuljahr 03-04\Informatik\Facharbeit\Cam_Einbindung_v01\main.cpp(173) : warning C4101: 'szFileName' : Unreferenzierte lokale Variable
Linker-Vorgang läuft...
main.obj : error LNK2001: Nichtaufgeloestes externes Symbol _capGetDriverDescriptionA@20
main.obj : error LNK2001: Nichtaufgeloestes externes Symbol _capCreateCaptureWindowA@32
Debug/Cam_Einbindung_v01.exe : fatal error LNK1120: 2 unaufgeloeste externe Verweise
Fehler beim Ausführen von link.exe.Cam_Einbindung_v01.exe - 3 Fehler, 1 Warnung(en)
Klickt man die Fehler an, springt er zu keiner Zeile.
Wie gesagt, ich habe durch den Code noch nicht ganz durchgeblickt !Danke
Romeo
-
Du hast wohl Vfw32.lib nicht gelinkt
-
Also ich weiss genau wer sich jetzt nen extra großes Eis verdient hat.
Kolpf dir selbst auf die Schulter.Ich danke dir viiieeelllmals.
Klappt wunderbar.
Also ... DDAAAAANNNNNKKKEEEEEE
P.S.: Wofür die diese lib eigentlich genau ???
-
Zu dlls gibt es meist auch eine passende Lib, damit die Verweise auf Funktionen in der DLL aufgelöst werden können
-
Romeo-G schrieb:
Da er aber seine resource.h nicht rausgerückt hat, musste ich den Code entsprechend kürzen.
sorry, muss ich überlesen haben, dass du die resource.h haben möchtest... wenn du die noch brauchst dann sag es. aber ich denke man kann den code zimlich schnell durchblicken und sich selbst eine zusammen basteln.
mfg
toom
-
So noch ne kleine Erweiterung.
Ich wollte mal PRobehalber nen TExt in die Mitte des Feldes schreiben.
Habe allerdings bemerkt, dass der TExt immer unter dem Video gezeichnet wird.Wie kann ich das ändern, weil der TExt ja inner mitte und nicht am oberen Rand oder ganz unten sein, wo ich mir PLatz geschaufelt hatte.
Danke
Romeo-G
-
Hi,
mal ne Frage zum Capture mittels VfW:Ich bastle gerade an einer Umsetzung mittels DirectShow
weil die Framerate bei der Wiedergabe scheinbar nie über
15fps kommt. Das Bild sieht bei Bewegungen immer so aus,
als wenn mittendrin Bilder fehlen würden.
capPreviewRate (hwndVideo, 33.3) mit anderen Werten haben keine
Auswirkung, meine Hardware ist, wenn ich den GraphEdit von DiretX nehme
und mir mal eben schnell einen Filter zurecht klickere, durchaus in der
Lage 30fps zu realisieren.@Romeo-G: Läuft das bei Dir wirklich mit voller Bildrate?
Gruß,
Colonius
-
capPreviewRate (hwndVideo, 33.3) mit anderen Werten haben keine
Auswirkung, meine Hardware ist, wenn ich den GraphEdit von DiretX nehme
und mir mal eben schnell einen Filter zurecht klickere, durchaus in der
Lage 30fps zu realisieren.Dass "capPreviewRate" bei mir auch keine wirklich erkennbaren Auswirkungen hatte habe ich auch schon rausgefunden.
Aber deinen deinen Lösungsansatz hatte habe ich noch nicht so ganz verstanden.
Kannst du nochmal genauer drauf eingehenbzw. den entsprechenden Code posten ???Danke
Romeo-GP.S: Das hat aber nicht wirklich was damit zu tun, dass das Child meinen TExt übermalt. Damit kann man doch nur dafür sorgen, dass wenn man sich schnell BEwegt, das Bild nicht ganz so "verschmiert" aussieht, oder ????
-
Hast du es denn jetzt schonmal mit subclassing versucht?
-
P.S: Das hat aber nicht wirklich was damit zu tun, dass das Child meinen TExt übermalt. Damit kann man doch nur dafür sorgen, dass wenn man sich schnell BEwegt, das Bild nicht ganz so "verschmiert" aussieht, oder ????
Hi,
nein, hat es nicht. Aber wenn man den steinigen Weg mit DirectX beschreitet und irgendwann mal verstanden hat, funktioniert das ganze mit vernünftiger Framerate, und Texteinblendungen dürften dann auch kein Problem sein (Mir ging es in erster Linie um dieses "verruckelte" Bild, auch bei langsamen Bewegungen)
Code kann ich momentan noch nicht bieten, da ich noch forscheSaug Dir das DirectX SDK in der aktuellen Version, da ist ein Tool dabei mit Namen "GraphEdit". Damit kann man, wenn man die Grundlagen verstanden hat, sich Filter und Graphen zusammenklicken (darauf baut DirectShow auf) und die
Auswirkungen sofort sehen.bietet schonmal einen Überblick, das SDK gibts bei den Downloads (224MB!!)
Gruß,
Colonius