Autor |
Beitrag |
mtin
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: Di 24.01.06 23:14
tja, also ich hab eine firewire webcam und probleme diese aus delphi anzusteuern!!
hab mich shcon n bisschnen umgeschaut, die codebeispiele liefern mir immer nur das Signal des 1. video -treibers, meiner TV-Karte...und nicht das der Webcam!!
z.b. der code hier funktioniert zwar wunderbar, aber eben nur für meine TV-Karte :/
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TForm1 = class(TForm) Panel1: TPanel; procedure FormCreate(Sender: TObject); private public end;
var Form1: TForm1;
const WM_CAP_DRIVER_CONNECT = WM_USER + 10; WM_CAP_EDIT_COPY = WM_USER + 30; WM_CAP_SET_PREVIEW = WM_USER + 50; WM_CAP_SET_OVERLAY = WM_USER + 51; WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
implementation
{$R *.dfm}
function capCreateCaptureWindow(lpszWindowName: LPCSTR; dwStyle: DWORD; x, y, nWidth, nHeight: integer; hwndParent: HWND; nID: integer): HWND; stdcall; external 'AVICAP32.DLL' name 'capCreateCaptureWindowA';
procedure TForm1.Formcreate; var handle:THandle; begin handle := capCreateCaptureWindow('Video',ws_child+ws_visible, 0, 0, 320, 240, Panel1.Handle, 1); SendMessage(handle, WM_CAP_DRIVER_CONNECT, 0, 0); SendMessage(handle, WM_CAP_SET_PREVIEWRATE, 30, 0); sendMessage(handle, WM_CAP_SET_OVERLAY, 1, 0); SendMessage(handle, wm_cap_set_preview, 1, 0); end;
end. |
auch wenn ich da in dem markierten 1,0 oder 2,0 schreibe geht es nicht! dann kommt nur ein schwarzes Bild...in anderen Programmen kann ich aber immer auswählen:
1. Medion (7134) WDM Video Capture (<-- tv-karte)
2. Standard 1394 Desktop camera
wie könnte ich das in delphi machen?
und ich weiß...für jede Frage ein thread...aber das sind nur son paar kleine Randfragen  :
das wäre für ein Info"Projekt", hab mir da mit nem Freund überlegt, dass wir sowas wie "EyeToy" oder so machen könnten, also mit der Hand die Maus steuern oder so diverse kleine Sachen mit der Kamera eben...und da frag ich mich jetzt, wie man da am besten rangeht...weil ich glaub kaum dass das Programm schnell genug läuft, wenn ich jede sekunde 30 mal jeden einzelnen Pixel über Image1.Canvas.Pixels auf seine Farbe untersuche....oder etwa doch?
vielleicht gibt es ja irgendeine schnellere möglichkeit...falles es denn zu langsam ist
Moderiert von Gausi: Überflüssig gewordenes Schiebeposting entfernt.
|
|
mtin 
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: Fr 27.01.06 18:42
hey....bin sonst echt aufgeschmissen weil im internet auch speziell zu FireWire webcams kaum was zu finden ist!!!
|
|
Mister X-Ray
      
Beiträge: 41
Win XP, Win 2000
D7 Pers, D2005 Pers
|
Verfasst: Fr 27.01.06 20:08
hallo,
ich hatte mal ein ähnliches problem, ich wollte einen DV-Camcorder (der über FW am PC angeschlossen ist) steuern bzw. mir ne Vorschau anzeigen lassen. Hab damals auch keine Antwort bekommen.
Das scheint ein Mysterium zu sein dass keiner so richtig versteht.
Noch viel Glück bei deiner Suche und lass mich wissen wenn du doch noch Erfolg hast
Gruß
Mister X-Ray
_________________ Wissen ist Macht, aber nichts wissen macht nichts !
|
|
mtin 
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: Sa 28.01.06 21:26
habs mehr oder weniger gelöst...auch wenn diese Variante alles andere als sauber ist
hab einfach den code um das Video zu übertragen doppelt reingeschrieben, dadurch kommt es zu einem Fehler und ein windows-fenster öffnet sich, in dem man das Video-Interface auswählen kann das man benutzen will...und wenn ich da meine FireWire Webcam auswähle dann kommt die immer, auch wenn ich dann diese verdopplung des codes wieder rausnehme!
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Formcreate; var handle:THandle; begin handle := capCreateCaptureWindow('Video',ws_child+ws_visible, 0, 0, 320, 240, Form1.Handle, 0); SendMessage(handle, WM_CAP_DRIVER_CONNECT, 0, 0); SendMessage(handle, WM_CAP_SET_PREVIEWRATE, 30, 0); sendMessage(handle, WM_CAP_SET_OVERLAY, 1, 0); SendMessage(handle, wm_cap_set_preview, 1, 0); handle := capCreateCaptureWindow('Video',ws_child+ws_visible, 0, 0, Form1.width, Form1.Height, Form1.Handle, 0); SendMessage(handle, WM_CAP_DRIVER_CONNECT, 0, 0); SendMessage(handle, WM_CAP_SET_PREVIEWRATE, 30, 0); sendMessage(handle, WM_CAP_SET_OVERLAY, 1, 0); SendMessage(handle, wm_cap_set_preview, 1, 0); end; |
das Windows-Fenster:
[url= img479.imageshack.us...2820062023575hd.jpg] [/URL]
|
|
Matthias
      
Beiträge: 121
|
Verfasst: So 29.01.06 16:51
Hallo,
Bei Video for Windows gibt es noch jede Menge weiterer Aufrufe.
z.B.
die folgenden zur Anzeige der Dialoge zum Einstellen des VideoSource, Videoformats und des Displays. Ich hoffe es hilft weiter.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START+ 41); WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START+ 42); WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START+ 43); WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START+ 44); WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START+ 45); WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START+ 46);
SendMessage(hwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0); SendMessage(hwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0); SendMessage(hwnd, WM_CAP_DLG_VIDEODISPLAY, 0, 0); |
ciao
Matthias
|
|
mtin 
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: So 29.01.06 19:46
danke!
das SendMessage(handle, WM_CAP_DLG_VIDEOSOURCE, 0, 0); hat mir echt geholfen, macht sich denk ich auch besser als meine Problemlösung
auch wenns trotzdem komisch ist, dass ich die Videoquelle nicht einfach so angeben kann...also nur über diesen Dialog!
|
|
Matthias
      
Beiträge: 121
|
Verfasst: So 29.01.06 23:34
Hallo
Du verwendest den Aufruf WM_CAP_DRIVER_CONNECT. Dieser ist folgendermaßen definiert:
WM_CAP_DRIVER_CONNECT = (WM_CAP_START+ 10);
SendMessage(hwnd, WM_CAP_DRIVER_CONNECT, WPARAM(DriverIndex), 0).
Das heißt, dass Du beim öffnen das Gerät (als z.B. deine Kameras auswählen kannst). Es gibt auch die Möglichkeit eine Liste
aller Geräte zu erhalten:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| function capGetDriverDescription ( wDriverIndex : DWord; lpszName : PChar; cbName : Integer; lpszVer : PChar; cbVer : Integer ) : Boolean; stdcall; external AVICAP32 name 'capGetDriverDescriptionA';
function GetDriverList:TStringList; var i : integer; name: array[0..127] of char; ver : array[0..127] of char; begin result:= TStringList.Create; i := 0; while capGetDriverDescription( i,name,127,ver,127) do begin result.Add(StrPas(name) + ' ' + strpas(ver)); inc(i); end; end; |
ciao
Matthias
|
|
mtin 
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: Mo 30.01.06 17:24
das sind aber Unterschiedliche sachen!!!
hier mal ein Screenshot, die Ausgabe deiner Funktion (Memo1.Text:=GetDriverList.Text) liefert das was da im Memo steht, in dem Dialog kann ich aber auch meine Webcam auswählen!!!!
[url= img217.imageshack.us...3020061623513fs.jpg] [/URL]
aber das ist ja auch nicht mehr so wichtig, es funktioniert ja mit dem Auswahldialog...
aber hätte trotzdem noch eine Frage: Wie kann ich diese Bilder jetzt möglichst in Echtzeit auswerten? also irgendwie in eine Bitmap oder ein Image reinbekommen bzw. als bmp speichern (falls das schnell genug ist um pro Sekunde so um die 10 Bilder auszuwerten)
|
|
Matthias
      
Beiträge: 121
|
Verfasst: Mi 01.02.06 10:26
Hallo,
das mit den Videoquellen habe ich nicht getestet; ich werde es aber bei Gelegenheit probieren. Für Dein Problem mit der Bitmap hier ein Ansatz.
Zuerst must Du eine Callbackfunktion inittialisieren.
Sie ist von folgendem Typ:
type
TCAPVIDEOSTREAMCALLBACK = function(hWnd:HWND; lpVHdr:PVIDEOHDR):LongInt; stdcall;
Teile dies VFW mit:
// WM_CAP_SET_CALLBACK_FRAME = (WM_CAP_START+ 5);
SendMessage(hwnd, WM_CAP_SET_CALLBACK_FRAME, 0,LPARAM(@OnCapVidostream));
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure TMainForm.OnCapVidostream(hWnd:HWND; lpVhdr: PVIDEOHDR); var ABmp : TBitmap; BmpInfo : TBitmapInfo; hdb :Thandle; begin ABmp := TBitmap.Create; ABmp.Pixelformat:= pf32bit;
SendMessage(hwnd, WM_CAP_GET_VIDEOFORMAT, Wparam(SizeOf(BmpInfo)), LPARAM(@BmpInfo)); with ABmp do begin Width := BmpInfo.bmiHeader.biWidth; Height := BmpInfo.bmiHeader.biHeight; hdb := DrawDibOpen; DrawDibDraw(hdb, canvas.handle,0,0, BmpInfo.BmiHeader.biwidth, BmpInfo.bmiheader.biheight, @BmpInfo.bmiHeader, lpvhdr^.lpdata, 0,0,BmpInfo.bmiHeader.biWidth, BmpInfo.bmiHeader.biheight,0); DrawDibClose(hdb); end;
ABmp.free; end; |
Ich habe den Code nicht weiter getestet. Es könnte alos sein, dass er ein paar kleine Fehler enthält. Grundsätzlich sollte es aber funktionieren.
ciao
Matthias
|
|
mtin 
      
Beiträge: 177
Win XP SP2
BDS2006 Enterprise
|
Verfasst: Do 02.02.06 19:52
hmpf, das schaut ja erstmal mächtig kompliziert aus!!
hab irgendwoanders etwas gefunden was mit der Zwischenablage arbeitet, ist das langsamer als deine Methode?
wenn nich, dann würd ich natürlich eher die hier nehmen weil das ist bedeutend kürzer und ich verstehs sogar  (was bei dem callback-spaß nich der Fall is -.- )
Delphi-Quelltext 1: 2:
| SendMessage( handle, WM_CAP_EDIT_COPY, 1, 0 ); Form1.image1.Picture.Bitmap.LoadFromClipboardFormat(cf_BitMap,ClipBoard.GetAsHandle(cf_Bitmap),0); |
mein einziges Problem ist das das ganze nicht funktioniert, wenn ich eine Bitmap nehme...ich muss irgendwie ein Image nehmen! jemand ne Ahnung woran das liegt?
|
|
Matthias
      
Beiträge: 121
|
Verfasst: Fr 03.02.06 10:52
Hallo,
1. ja es ist langsamer.
2. mit der Zwischenablage ist das so eine Sache (Farbtiefe, Auflösung, andere Anwendungen)
In der Vergangaenheit habe ich auch die Methode mit der Zwischenablage benutzt. Wirlich glücklich gworden bin ich damit nicht.
Wenn Du keine Lust hast alles selbst zu programmieren verwende doch z.B. die Kompo von J.Hübler.
homepages.borland.co...video/jhvideocap.zip
Dort ist unter anderem eine Demo dabei, die Bilder von der Kamera direkt in eine Bitmap "pumpt".
ciao
Matthias
|
|
|