Autor Beitrag
mtin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Sa 11.03.06 15:34 
also, nachdem ich mich jetzt schon ein bisschen damit beschäftigt hab,
kann ich in einem Panel das webcam-bild darstellen und per
ausblenden Delphi-Quelltext
1:
2:
 SendMessage( handle, WM_CAP_EDIT_COPY, 1, 0 );
Form1.image1.Picture.Bitmap.LoadFromClipboardFormat(cf_BitMap,ClipBoard.GetAsHandle(cf_Bitmap),0);
die Bilder in halbwegs akzeptabler geschwindigkeit (praktisch noch live) in ein Bitmap/Image kopieren...
Doch wie erreiche ich das, ohne ein Panel irgendwo auf dem Form zu haben? Also praktisch nur mit irgendeinem Befehl EIN Frame von der webcam holen, ohne die ganze Zeit das bild live anzuschaun? Bzw. einfach live die Bilder verarbeiten und das Ergebnis der Verarbeitung dann anzeigen?
Im Moment muss ich immer das Panel und dann daneben mein TImage haben, obwohl ich lieber z.b. nur mit dem TImage im Vollbildmodus arbeiten würde!

Bei irgendwelchen webcamprogrammen geht das ja auch, dass man das im Hintergrund aufnimmt oder wenns minimiert ist...

wäre für jede Hilfe, die die webcambilder ohne panel o.ä. in ein bitmap pumpt, dankbar!
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: So 12.03.06 17:24 
okee, hab das jetzt mit der CallBack-Prozedur probiert, das ist schonmal besser als mit der zwischenablage und ich kann das Panel auch ganz klein machen und das funktioniert trotzdem noch, sobald ich aber das Panel auf Visible:=False stelle, geht es auch nicht mehr...ich will aber nicht dieses verdammte Panel irgendwo sehen!!!!

gibt es da irgendeine Möglichkeit?
Matthias-K
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 271

Win95, Win98, Win2000, WinXP, Linux
D2, D4 Client/Server, D5 Enterprise, D6 Enterprise, D7 Enterprise, Delphi2005, C/C++ 3.0, C/C ++ 5.0, C/C++ 6.0
BeitragVerfasst: Mo 13.03.06 16:47 
moin, zeig mal deinen quellcode her! ma sehn, was de da fabriziert hast.

mfg matthias

_________________
Ein Spezialist ist ein Mensch, der immer mehr von immer weniger weis, bis er alles von nichts weis!
schlumpf070
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 16



BeitragVerfasst: Mo 13.03.06 17:26 
user profile iconmtin hat folgendes geschrieben:
okee, hab das jetzt mit der CallBack-Prozedur probiert, das ist schonmal besser als mit der zwischenablage und ich kann das Panel auch ganz klein machen und das funktioniert trotzdem noch, sobald ich aber das Panel auf Visible:=False stelle, geht es auch nicht mehr...ich will aber nicht dieses verdammte Panel irgendwo sehen!!!!

gibt es da irgendeine Möglichkeit?


haste mal versucht height und width auf 0 zu setzen ?
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Di 14.03.06 16:55 
width und height auf 0 hat die gleiche Auswirkung wie Invisible!
allerdings hab ich das jetzt nochmal probiert, es klappt trotzdem, nur wird nicht fortlaufend das bild "gecaptured" sondern nur ein einziges mal sobald ich die message sende. Normalerweise, also wenn das Panel sichtbar/eine breite von 1 oder größer hat, dann werden automatisch hintereinanderweg die ganze Zeit die frames gecaptured, aber sobald das Teil invisible ist nur noch sobald ich die message sende...also wenn ich den Button auswähle und Enter gedrückt halte klappts auch, aber ich denkma das ist langsamer wenn ich die message immer sende als normal, oder?

egal hier is der code, wer eine Webcam hat un das mal ausprobieren möchte...
einfach ein 320x240 Panel un ein 320x240 TImage daneben und einen Button drunter.
Dann ein klick auf Button1click, einen auf FormCreate und einen auf FormDestroy

ausblenden volle Höhe Delphi-Quelltext
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:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
unit Unit1;

interface 

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, ExtCtrls, YUVConverts, StdCtrls, Clipbrd;

const
  WM_CAP_START = WM_USER; 
  WM_CAP_DRIVER_CONNECT       = WM_CAP_START + 10;
  WM_CAP_EDIT_COPY                = (WM_USER + 30);
  // WM_CAP_SET_PREVIEW ist NICHT hintergrundlauffähig 
  WM_CAP_SET_PREVIEW          = WM_CAP_START + 50; 
  WM_CAP_SET_OVERLAY          = WM_CAP_START + 51; 
  WM_CAP_SET_PREVIEWRATE      = WM_CAP_START + 52; 
  // WM_CAP_GRAB_FRAME_NOSTOP ist hintergrundlauffähig !!! 
  WM_CAP_GRAB_FRAME_NOSTOP    = WM_CAP_START + 61; 
  WM_CAP_SET_CALLBACK_FRAME   = WM_CAP_START + 5; 
  WM_CAP_GET_VIDEOFORMAT      = WM_CAP_START + 44; 

  WM_CAP_DLG_VIDEOFORMAT      = WM_CAP_START+41;
  WM_CAP_DLG_VIDEOSOURCE       = (WM_USER + 42);

  PicWidth = 320;
  PicHeight = 240;

type 
  TVIDEOHDR = record  
    lpData : Pointer; // address of video buffer 
    dwBufferLength : DWord; // size, in bytes, of the Data buffer 
    dwBytesUsed : DWord; // see below 
    dwTimeCaptured : DWord; // see below 
    dwUser : DWord; // user-specific data 
    dwFlags : DWord; // see below 
    dwReserved1, dwReserved2, dwReserved3 : DWord; // reserved; do not use 
  end; 
  TVIDEOHDRPtr = ^TVideoHDR; 

  DWordDim = array[1..PicWidth] of DWord; 

  TForm1 = class(TForm) 
    Panel1: TPanel;
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject); 
    procedure FormCreate(Sender: TObject);


  private
    FCapHandle : THandle; 
    FCodec : TVideoCodec; 
    FGrabFrameFlag : Boolean;
    FBuf1,FBuf2 : array[1..PicHeight] of DWordDim; 
    FBitmap : TBitmap; 
    { Private-Deklarationen } 
  public 
    { Public-Deklarationen } 
  end; 

var 
  Form1: TForm1;
  zeit:integer;

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'; 

//------------------------------------------------------------------------------ 
// FrameCallbackFunction 

function FrameCallbackFunction(AHandle : hWnd; VIDEOHDR : TVideoHDRPtr): bool; stdcall; 
var I : integer;
begin 
  result := true;

  with form1 do begin
    ConvertCodecToRGB(FCODEC, VideoHDR^.lpData, @FBuf2,PicWidth, PicHeight);
    for I := 1 to PicHeight do FBuf1[I] := FBuf2[PicHeight -(I-1)];
    SetBitmapBits(FBitmap.Handle,PicWidth*PicHeight*SizeOf(DWord),@FBuf1); 
    Image1.Picture.Bitmap:=FBitmap;
    application.ProcessMessages;
  end;
end; 

//------------------------------------------------------------------------------ 

procedure TForm1.FormCreate(Sender: TObject); 
var  BitmapInfo: TBitmapInfo; 
begin 


  FBitmap := TBitmap.Create; 
  FBitmap.Width := PicWidth; 
  FBitmap.Height := PicHeight; 
  FBitmap.PixelFormat := pf32Bit; 

  FCapHandle := capCreateCaptureWindow('Video',ws_child+ws_visible, 0, 0, 
  PicWidth, PicHeight, Panel1.Handle, 1);
  SendMessage(FCapHandle, WM_CAP_DRIVER_CONNECT, 0, 0); 
  SendMessage(FCapHandle, WM_CAP_SET_PREVIEWRATE, 1, 0);
  sendMessage(FCapHandle, WM_CAP_SET_OVERLAY, 1, 0);
  SendMessage(FCapHandle, WM_CAP_SET_PREVIEW, 1, 0);
//  SendMessage(FCapHandle,WM_CAP_DLG_VIDEOFORMAT,1,0);
//  SendMessage(FCapHandle,WM_CAP_DLG_VIDEOSOURCE,1,0);

  FillChar(BitmapInfo, SizeOf(BitmapInfo), 0); 
  SendMessage(FCapHandle, WM_CAP_GET_VIDEOFORMAT, SizeOf(BitmapInfo), Integer(@BitmapInfo)); 
  FCodec := BICompressionToVideoCodec(bitmapinfo.bmiHeader.biCompression); 
  if FCodec = vcUnknown then begin showmessage('unbekannter codec'); end;
end; 


procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  FBitmap.free; 
end; 


procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage(FCapHandle, WM_CAP_SET_CALLBACK_FRAME, 0, integer(@FrameCallbackFunction));
SendMessage(FCapHandle, WM_CAP_GRAB_FRAME_NOSTOP, 1, 0);
end;


end.
(die beiden kommentare in Zeile 115/116 entfernen um die Auswahldialoge anzuzeigen)

wenn keiner mehr ne idee hat werd ich wohl das Panel auf 1x1 stellen...obwohl ich immer noch nicht verstehe WARUM man überhaupt so ein Panel braucht...find ich total schwachsinnig! na egal :D

ahja und hat jemand noch eine Idee wie ich das am dümmsten Objektorientiert, also als funktion hinbekomme?
So dass ich dann z.b. Image1.Picture.Bitmap:=cam.grabframe; machen kann? für die Clipboard-Variante hatte ich das schon, aber ich weiß nich wie ich das bei dieser callback-function machen soll!
STB
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 25.03.06 20:24 
Hallo, ich bekomme laufend den Fehler :

Ich benutze die beiden Quelltextzeilen von mtin:

Unsupported clipboard format

Woran kann das liegen?

Habe schon mtin geschrieben, aber er wusste es leider nicht, habe clipbrd in uses eingefügt
geht aber nicht.

Benutzte D 6 Enterprise.

Würde mich über eine ANtwort freuen