Avatar billede mbsnet Nybegynder
15. maj 2010 - 10:48 Der er 10 kommentarer og
1 løsning

Webcam problem directShow9 bitmap panel

Hej eksperter...

Jeg får et billede fra webcam på et TPanel via DirectShow9 (virker).
Ønsker at konvertere til bitmap, skjule panelet,
og så vise modificeret bitmap via TImage i stedet.

Kan kopiere billedet over i en bitmap med
with aBmp,canvas do begin
bitblt(handle,0,0,width,height,getDc(Panel1.handle),0,0,SRCCOPY);
textOut(5,5,'test....');
end;


tests...
1. Hvis panelets "visible" sættes til False, vises intet i bitmap/timage.
2. Hvis panelet trækkes uden for formens synlige område, vises kun det synlige i bitmap'en.
3. Hvis et TImage placeres inden i panelet (alClient), vises det ikke (panelet vises)

Så.. problemet er altså at jeg ikke kan får bitmap, med mindre panelet er synligt.

Kan nogen hjælpe ?

Har tænkt om man muligvis kunne gå uden om at bruge panelet på en måde, -
om man kan bruge noget andet end panelet, -
eller om man kan få billedet selvom panelet ikke er synligt.

mvh
Morten B. S.


p.s. koden som benyttes
unit Unit1;

interface

uses
  windows,classes,controls,graphics,forms,extCtrls,comObj,activeX, directShow9;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Image1: TImage;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    pGraph      :iGraphBuilder;
    pBuilder    :iCaptureGraphBuilder2;
    pDevEnum    :iCreateDevEnum;
    pClassEnum  :iEnumMoniker;
    pMoniker    :iMoniker;
    pSrc        :iBaseFilter;
    cFetched    :pLongInt;
    videoWindow  :iVideoWindow;
    mediaControl :iMediaControl;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
image1.picture.bitmap:=tBitmap.create;
with image1.picture.bitmap do begin pixelFormat:=pf24bit;width:=image1.width;height:=image1.height end;
//--
pGraph:=createComObject(CLSID_FilterGraph) as iGraphBuilder;
pBuilder:=createComObject(CLSID_CaptureGraphBuilder2) as iCaptureGraphBuilder2;
pBuilder.SetFiltergraph(pGraph);
pDevEnum:=createComObject(CLSID_SystemDeviceEnum) as iCreateDevEnum;
pDevEnum.createClassEnumerator(CLSID_VideoInputDeviceCategory,pClassEnum,0);
if pClassEnum.next(1,pMoniker,cFetched)=S_OK then
pMoniker.bindToObject(nil,nil,IID_IBaseFilter,pSrc);
pGraph.addFilter(pSrc,'Video Capture');
pGraph.queryInterface(IID_IMediaControl,mediaControl);
pGraph.queryInterface(IID_IVideoWindow,videoWindow);
pBuilder.renderStream(@PIN_CATEGORY_PREVIEW,@MEDIATYPE_VIDEO,pSrc,nil,nil);
videoWindow.put_windowStyle(WS_CHILD or WS_CLIPSIBLINGS);
videoWindow.setWindowPosition(0,0,panel1.width,panel1.height);
videoWindow.put_owner(panel1.handle);
mediaControl.run;
timer1.interval:=250;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
with image1.picture.bitmap,canvas do begin
  bitblt(handle,0,0,width,height,getDc(Panel1.handle),0,0,SRCCOPY);
  textOut(5,5,'test....');
end;image1.refresh
end;

end.
Avatar billede martinlind Nybegynder
15. maj 2010 - 11:08 #1
har du prøvet at bruge din bitmap.handle som VideoWindow.put_owner osv.
Avatar billede mbsnet Nybegynder
15. maj 2010 - 11:36 #2
har lige forsøgt med:
//videoWindow.put_owner(fBmp.handle);
//videoWindow.put_owner(fBmp.canvas.handle);

Den laver en sort firkant på skrivebordet, og ellers vises intet i bitmap... Kan det være noget med det skal være et window dc ?
Avatar billede mbsnet Nybegynder
15. maj 2010 - 16:32 #3
Rettelse... Den laver ikke en sort firkant, men den viser videovinduet på skrivebordet i øverste venstre hjørne. Oplever nøjagtigt samme problem i forbindelse med VFW og capCreateCaptureWindow.
Avatar billede martinlind Nybegynder
15. maj 2010 - 22:12 #4
hmmm ... måske, hvad med at lave en form uden kanter og bruge den som "panel"
Avatar billede mbsnet Nybegynder
16. maj 2010 - 16:34 #5
Tjaa.. :) Ved ikke om man kan oprette en form for usynligt dc, og sætte størrelsen osv. Kigger også på "samplegrabber" i øjeblikket, men har svært ved at få forbundet de rigtige "pins". Det ville ellers være enkelt, hvis man kunne lave et usynligt dc...
Avatar billede martinlind Nybegynder
16. maj 2010 - 17:51 #6
Det kan du sagtens, visible := false så bliver den ikke vist :-)
En form har både message-loop og DC osv.
Avatar billede mbsnet Nybegynder
17. maj 2010 - 09:18 #7
Prøvede at oprette en Form2, som owner. Det virker kun hvis formen er synlig, ellers tror jeg det er bitBlt, som ikke kan hente data fra vinduet. (Det bliver sort hvis jeg minimerer/skjuler osv).

Hvis jeg bruger "CreateDC" til at oprette et handle, vises videovinduet igen på skrivebordet i øverste venstre hjørne.

fDC:=createDC('Display', nil, nil, nil);

Så ved ikke om man kan få VFW/DS til at tegne,- samt om man kan aflæse ikke-synlige DC.
Avatar billede mbsnet Nybegynder
17. maj 2010 - 13:57 #8
Men det er lige før det med formen kunne bruges som en løsning, for det virker rent faktisk hvis video-formen trækkes helt ud af det synlige skrivebord (venstre eller højre). Det ville dog være rart hvis vinduet ikke ligger der...
Avatar billede martinlind Nybegynder
17. maj 2010 - 20:18 #9
Der er også den der paintbox comp. måske den sammen med formen...
det med at du kan trække den "udenfor" skrivebordet er det ikke fordi du så ville kunne se den på en evt. skærm to ? bare et bud :-)
Avatar billede mbsnet Nybegynder
17. maj 2010 - 21:20 #10
Ja, kører i forvejen med flere skærme tilsluttet :)

Afprøver i øjeblikket hvordan det kører i forbindelse med en rutine jeg har benyttet tidligere:

function getWorkSpaceRect:tRect;
begin
result.left:=0;result.right:=getSystemMetrics(78);
result.top:=0;result.bottom:=getSystemMetrics(79);
offsetRect(result,getSystemMetrics(76),getSystemMetrics(77))
end;

Har i "OnResize":
form2.left:=getWorkSpaceRect.left-(form2.width*3);

Vil gerne senere kunne bruge "samplegrabber" /lign.
...Men har indtil nu brugt en langt værre løsning, med VFW som gemte 10fps via en fil.
Det har ikke været sundt for den harddisk, og programmet har kørt ringe...

Får nu en bitmap på omkring 5 ms/frame ved 720p, og programmet kører flydende.

Så i forhold til det, ser denne løsning allerede langt bedre ud. På sigt vil der måske opstå nogle problemer, hvis man ændrer på skærmopsætning osv,- men programmet skal køre på en server uden skærm tilsluttet (kun remote), så vil godt kunne leve med formen som den er.

Tak for hjælp igen, det er altid rart med en lille delphi snak,
så der er point hvis svar. :)
Avatar billede martinlind Nybegynder
18. maj 2010 - 00:54 #11
kom lige i tanke om DoubleBuffer har du prøvet at sætte den til tru på din Form2....

Så har jeg ikke flere foreslag i ærmet
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester