Changer de hWndC pour la capture WebCam ?!

Programmation d'applications complexes
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Changer de hWndC pour la capture WebCam ?!

Message par Mytic »

J’ai trouvé ce code dans le Forum anglais, et je lui ai fait quelques modifications.
Voilà le problème ! Comment afficher l’image de la Webcam directement dans une image sans passer par l’affichage sur Window puis prendre cette capture et la mettre dans une imageid ?
En gros changer le hWndC dans :
hWndC = CallFunctionFast(*capAddress, "My Capture Window", #WS_CHILD | #WS_VISIBLE, 50,38, 310, 230, WindowID(0),0)
par le hWndC de l’image crée avec Createimage()

Code : Tout sélectionner

UseJPEGImageEncoder()
UseJPEGImageDecoder()
Enumeration
 
  #Window_0
  #Button_0
  #Button_1
  #Button_2
  #Button_4
  #viewer1
  #gadget1
  #counter
  #counter1
  #name
  #takebut
  #viewbut
  #quitbut
EndEnumeration

Dim snapshot.l(50)
i=1
If OpenWindow(#Window_0, 100, 100, 408, 338, "Little Camera", #PB_Window_SystemMenu |  #PB_Window_MinimizeGadget     )

  If CreateGadgetList(WindowID(#Window_0))
   
    ButtonGadget(#Button_0, 150, 280, 50, 25, "Capture")
    ButtonGadget(#Button_1, 250, 280, 50, 25, "Quit")
    ButtonGadget(#Button_2, 200, 280, 50, 25, "Show")
    EndIf
   
   
   
  EndIf
 
Global hWndC.l
Global snapshot.l
Procedure.b initcam() 
pcvs.b = 0
CreateImage(0,400,400)
#WM_CAP_START = #WM_USER
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14
#WM_CAP_EDIT_COPY = #WM_CAP_START + 30
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_STOP = #WM_CAP_START + 68
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
  If OpenLibrary(0, "avicap32.dll")
    *capAddress = GetFunction(0, "capCreateCaptureWindowA")
    hWndC = CallFunctionFast(*capAddress, "My Capture Window", #WS_CHILD | #WS_VISIBLE, 50,38, 310, 230, WindowID(0),0)

    SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
    SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
    SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 1, 0)
    SendMessage_(hWndC, #WM_CAP_SET_SCALE, #True, 0)
 pcvs = 1   
    ;............................................(pour afficher l'option)
;#WM_CAP_START = #WM_USER
;#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42
;............................................
;SendMessage_(hWndC, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
  EndIf
ProcedureReturn pcvs
EndProcedure
Procedure.b capcam()
pcvs.b = 0
SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
snapshot = GetClipboardImage(#PB_Any)
If snapshot
saver$= "snapshot.jpg"
SaveImage(snapshot,saver$,#PB_ImagePlugin_JPEG,10)
;FreeImage(snapshot)
pcvs = 1
EndIf
ProcedureReturn pcvs
EndProcedure
Procedure destroycam()
SendMessage_(hWndC, #WM_CAP_STOP, 0, 0)
SendMessage_(hWndC, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
DestroyWindow_(hWndC)
CloseLibrary(0)
EndProcedure
initcam()

 ;HideWindow(0,1)
Repeat
  Event=WaitWindowEvent(10)

  Select Event
   
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_0

          
capcam()
           

          
        Case #Button_1
          SendMessage_(hWndC, #WM_CAP_STOP, 0, 0)
          SendMessage_(hWndC, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
          DestroyWindow_(hWndC)
           CloseLibrary(0)
          End
         
        Case #Button_2
         
          If OpenWindow(#viewer1, 10, 10, 340, 270, "ImageGadget", #PB_Window_ScreenCentered|#PB_Window_BorderLess    )
            StickyWindow(#viewer1, 1)
            If CreateGadgetList((WindowID(#viewer1)))
         
              existimage=  LoadImage(0, saver$)     ;Path/filename of the image
              If existimage
              ImageGadget(#gadget1,  10, 10, 310, 230, ImageID(0),#PB_Image_Border)                      ; imagegadget standard
            Else
              ResizeWindow(#viewer1,#PB_Ignore ,#PB_Ignore ,10,10)
             
              MessageRequester("No Image", "image doesn,t exist",#PB_MessageRequester_Ok)
              CloseWindow(#viewer1)
              quit=1
              EndIf
             
          EndIf
          
            Repeat
              event2=WaitWindowEvent()
              bugger=EventType()
              Select bugger
                Case #PB_EventType_RightClick
                  CloseWindow(#viewer1)
                  quit=1
                 
              EndSelect
            Until quit=1
          EndIf
          quit=0
       
      EndSelect
  EndSelect
 

 
Until Event = #PB_Event_CloseWindow

destroycam()

End 
:idea: :?:
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Y'a quelqu'un un un .................... :cry:
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Je viens de lire la MSDN et il me semble que tu sois obligé de passer par une fenêtre windows.
Par contre, ce que tu peux faire, c'est en créer une invisible et dans la fonction callback de capture, écrire les données dans une image que tu auras préalablement initialisé à la taille de la vidéo (ne le fait pas dans la callback).
"Qui baise trop bouffe un poil." P. Desproges
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Est-ce que tu peux récupérer la largeur et la hauteur précise de l'image affichée à l'écran et créée par la caméra?
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

>KarLKoX<
Oui malheureusement c’est le seul moyen…
Y’a pas une autre façon de procéder avec une DLL Windows intégrée ?

>Ollivier<
Tu peux obtenir ces infos après ça :

Code : Tout sélectionner

SendMessage_(hWndC, #WM_CAP_EDIT_COPY, 0, 0)
snapshot = GetClipboardImage(#PB_Any)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Ah non je suis une burne. (Question stupide)

Essaie ça pour voir:

Code : Tout sélectionner

hWndC = CallFunctionFast(*capAddress, "My Capture Window", #WS_CHILD | #WS_VISIBLE, 50,38, 310, 230, StartDrawing(ImageID(MonImageCreePlusHaut) ),0) 
Repeat
; Procédure d'attente d'appui sur une touche
Until
StopDrawing
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Non ça a peu de chance que ça marche parce que normalement on lui donne un l'ID de la fenêtre (c'est avec cet ID qu'il récupère le DC de la fenêtre). Donc si on lui donne un DC directement ça va pas lui plaire...

T'as trouvé où cette fonction que je la mate un peu en ASM. Si j'ai l'adresse du port, la largeur de ligne de la camera, la profondeur d'un pixel, je te fais un hardcopy sur un peu de tout, image, sprite, zone mémoire, etc... Ce serait plus simple que de passer par une fenêtre.

EDIT:j'ai eu du mal à me comprendre moi-m^me. Je susi fatigué. Mais ton histoire va faire que demain soir je vais m'acheter une webcam juste pour tester ce truc bien sympa.
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Cette DLL ne permet l’envoi que sur un Window , donc faut chercher un autre moyen
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

"Cette DLL permet..." Oui okay Mytic, mais cette DLL c'est aussi du code ASM que tu peux mater avec l'assembleur en ligne (cf aide PB >> mini débogueur)!!!! Et là tu auras tout ce qu'il faut pour faire un hardcopy! Tu veux que je la récupère cette DLL?
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Oui oui , ça serai vraiment sympa de ta part :D
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

J'ai même pas l'adresse :D Bon on va faire une recherche avec 'capCreateCaptureWindowA'...
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Pour la Dll elle se trouve dans ce dossier :
C:\WINDOWS\system32\avicap32.dll
:wink:
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

P... je l'ai déjà? Sans blague!
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Tiens et n'enlève pas le débogueur. Je commences par la fin. Tu commence le début.
On recherche tous les instructions
IN INS INSB INSW INSD noter toutes les valeurs à droite de ces instrus
OUT OUTS OUTSB OUTSW OUTSD noter toutes les valeurs à droite de ces instrus
CALL noter toutes les valeurs à droite de ces instrus + Nom de la fonction (c'est marqué plus haut, tu défiles avec la brre du débogueur)
Ok?

Code : Tout sélectionner

Procedure.l Hex2Dec(h$) 
  h$=UCase(h$) 
  For r=1 To Len(h$) 
    d<<4 : a$=Mid(h$,r,1) 
    If Asc(a$)>60 
      d+Asc(a$)-55 
    Else 
      d+Asc(a$)-48 
    EndIf 
  Next 
  ProcedureReturn d 
EndProcedure 

Procedure GetNumberOfParam(Pointer) 
  Repeat 
    Pointer=DisASMCommand(Pointer) 
    ASM_Code.s=UCase(GetDisASMString()) 
    Debug "   " + ASM_Code.s
  Until FindString(ASM_Code.s,"RET",1) 
  Debug "}"
  MessageRequester("Message", "Cliquez sur Ok pour explorer la fonction suivante.", #PB_MessageRequester_Ok)
  Bytes=Hex2Dec(Right(ASM_Code.s,Len(ASM_Code.s)-4)) 
  If Bytes%4 Or Bytes>200:Bytes=-1:EndIf 
  If Bytes>=0:Bytes=Bytes>>2:EndIf 
  If Bytes < 0 : Bytes = 0 : EndIf 
  ProcedureReturn Bytes 
EndProcedure

DLLFichierNom$ = "C:\WINDOWS\system32\avicap32.DLL"

Debug("Ouverture de la librairie " + DLLFichierNom$)
If OpenLibrary(0, DLLFichierNom$)
  If IsLibrary(0)
    Debug("Librairie valide")
    QFB = CountLibraryFunctions(0)
    Debug(Str(QFB) + " fonction(s) détectées")
    If ExamineLibraryFunctions(0)
      N = 0
      Debug("L'examen des fonctions est possible")
      For N = 0 To QFB
        Result = NextLibraryFunction()
        If Result
          FNom$ = LibraryFunctionName()
          Debug(FNom$ + "{")
          Adr = LibraryFunctionAddress()       
          nParam = GetNumberOfParam(Adr)
          Debug(Str(N) + ": " + FNom$ + "  >>  [" + Hex(Adr) + "] [" + Hex(nParam) + "]")          
          ;*F = GetFunction(0, "MessageBoxA")
          ;If *F
          ;  CallFunctionFast(*F, 0, "Body", "Title", 0)
          ;EndIf
        Else
          Debug("Fin de la liste des fonctions!")
        EndIf
      Next
    Else
      Debug("Impossible d'examiner les fonctions!")
    EndIf
  Else
    Debug("Librairie invalide!")
  EndIf
  CloseLibrary(0)
EndIf

Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

De visu, c'est pas cette DLL qui fait les E/S : elle en appelle au moins une autre.
Pour ça il faut scanner le fichier DLL pour y trouver les autres noms et là je t'assure, je commence à 5h30 tout à l'heure. Je verrai ça demain si le temps s'y prète.

PS: Au passage, petit code pour savoir le nombre de paramètres qu'il faut rentrer quand on ne connait rien de la fonction!! Avec la valeur à droite du dernier RET de chaque fonction. si c'est RET 0004, c'est 1 paramètre, RET 0008, 2 valeurs, etc...
Répondre