Je veux écrire un programme de capture d'écran pour la plate-forme Windows, mais je ne sais pas comment capturer l'écran. La seule méthode que je connaisse est d'utiliser GDI, mais je suis curieux de savoir s'il existe d'autres façons de procéder et, s'il y en a, laquelle entraîne le moins de frais généraux? La vitesse est une priorité.
Le programme de screencasting sera pour enregistrer des séquences de jeu, bien que, si cela restreint les options, je suis toujours ouvert à toute autre suggestion qui ne relève pas de cette portée. La connaissance n'est pas mauvaise, après tout.
Edit : Je suis tombé sur cet article: Diverses méthodes pour capturer l'écran . Il m'a présenté la manière de procéder de l'API Windows Media et la manière de procéder par DirectX. Il mentionne dans la conclusion que la désactivation de l'accélération matérielle pourrait considérablement améliorer les performances de l'application de capture. Je suis curieux de savoir pourquoi. Quelqu'un pourrait-il remplir les espaces manquants pour moi?
Edit : J'ai lu que les programmes de screencasting tels que Camtasia utilisent leur propre pilote de capture. Quelqu'un pourrait-il m'expliquer en profondeur comment cela fonctionne et pourquoi c'est plus rapide? J'ai peut-être également besoin de conseils sur la mise en œuvre de quelque chose comme ça, mais je suis sûr qu'il existe de toute façon une documentation existante.
De plus, je sais maintenant comment FRAPS enregistre l'écran. Il accroche l'API graphique sous-jacente pour lire à partir du tampon arrière. D'après ce que je comprends, c'est plus rapide que la lecture à partir du tampon avant, car vous lisez à partir de la RAM système plutôt que de la RAM vidéo. Vous pouvez lire l'article ici .
MovePlayerLeft()
. Et vous enregistrez également l'heure et la durée des pressions sur les touches et autres entrées. Ensuite, lorsque vous êtes en mode lecture, vous ignorez simplement l'entrée et lisez à la place les données enregistrées. Si, dans les données, vous voyez une touche gauche, vous appelezMovePlayerLeft()
.Réponses:
C'est ce que j'utilise pour collecter des images uniques, mais si vous modifiez ceci et gardez les deux cibles ouvertes tout le temps, vous pouvez le «streamer» sur le disque en utilisant un compteur statique pour le nom de fichier. - Je ne me souviens plus où j'ai trouvé ça, mais ça a été modifié, merci à qui que ce soit!
la source
EDIT: Je peux voir que cela est répertorié sous votre premier lien d'édition comme "la manière GDI". C'est toujours une manière décente d'aller même avec l'avis de performance sur ce site, vous pouvez facilement atteindre 30fps, je pense.
D'après ce commentaire (je n'ai aucune expérience en la matière, je fais simplement référence à quelqu'un qui le fait):
Je ne dis pas que c'est le plus rapide, mais l'
BitBlt
opération est généralement très rapide si vous copiez entre des contextes d'appareils compatibles.Pour référence, Open Broadcaster Software implémente quelque chose comme ça dans le cadre de sa méthode "dc_capture" , bien qu'au lieu de créer le contexte de destination en
hDest
utilisant,CreateCompatibleDC
ils utilisent unIDXGISurface1
, qui fonctionne avec DirectX 10+. S'il n'y a pas de soutien pour cela, ils se rabattentCreateCompatibleDC
.Pour le changer pour utiliser une application spécifique, vous devez changer la première ligne en
GetDC(game)
où segame
trouve la poignée de la fenêtre du jeu, puis définir la droiteheight
etwidth
la fenêtre du jeu également.Une fois que vous avez les pixels dans hDest / hbDesktop, vous devez toujours les enregistrer dans un fichier, mais si vous effectuez une capture d'écran, je pense que vous voudriez en mettre un certain nombre en mémoire tampon et les enregistrer dans le fichier vidéo en morceaux, je ne pointerai donc pas vers le code pour enregistrer une image statique sur le disque.
la source
J'ai écrit un logiciel de capture vidéo, similaire à FRAPS pour les applications DirectX. Le code source est disponible et mon article explique la technique générale. Regardez http://blog.nektra.com/main/2013/07/23/instrumenting-direct3d-applications-to-capture-video-and-calculate-frames-per-second/
Respect de vos questions liées à la performance,
DirectX devrait être plus rapide que GDI, sauf lorsque vous lisez à partir du tampon frontal qui est très lent. Mon approche est similaire à FRAPS (lecture de backbuffer). J'intercepte un ensemble de méthodes des interfaces Direct3D.
Pour l'enregistrement vidéo en temps réel (avec un impact minimal sur l'application), un codec rapide est essentiel. FRAPS utilise son propre codec vidéo sans perte. Lagarith et HUFFYUV sont des codecs vidéo génériques sans perte conçus pour les applications en temps réel. Vous devriez les regarder si vous souhaitez sortir des fichiers vidéo.
Une autre approche pour enregistrer des screencasts pourrait être d'écrire un pilote miroir. Selon Wikipedia: Lorsque la mise en miroir vidéo est active, chaque fois que le système dessine vers le périphérique vidéo principal à un emplacement à l'intérieur de la zone en miroir, une copie de l'opération de dessin est exécutée sur le périphérique vidéo en miroir en temps réel. Consultez les pilotes miroir sur MSDN: http://msdn.microsoft.com/en-us/library/windows/hardware/ff568315(v=vs.85).aspx .
la source
J'utilise d3d9 pour obtenir le backbuffer et je l'enregistre dans un fichier png en utilisant la bibliothèque d3dx:
Pour ce faire, vous devez créer votre swapbuffer avec
(Vous garantissez donc que le backbuffer n'est pas mutilé avant de prendre la capture d'écran).
la source
GetRenderTarget
est?Dans mon impression, l'approche GDI et l'approche DX sont de nature différente. la peinture à l'aide de GDI applique la méthode FLUSH, l'approche FLUSH dessine le cadre puis l'efface et redessine une autre image dans le même tampon, cela entraînera un scintillement dans les jeux nécessitant une fréquence d'images élevée.
Je pense que ce dont vous avez vraiment besoin, c'est d'un système de relecture, dont je suis totalement d'accord avec ce dont les gens ont discuté.
la source
J'ai écrit une classe qui implémentait la méthode GDI pour la capture d'écran. Moi aussi, je voulais une vitesse supplémentaire, donc après avoir découvert la méthode DirectX (via GetFrontBuffer), j'ai essayé cela, en m'attendant à ce qu'elle soit plus rapide.
J'ai été consterné de constater que GDI fonctionne environ 2,5 fois plus vite. Après 100 essais capturant mon affichage à deux moniteurs, l'implémentation GDI en moyenne 0,65 s par capture d'écran, tandis que la méthode DirectX en moyenne 1,72 s. Donc, GDI est définitivement plus rapide que GetFrontBuffer, d'après mes tests.
Je n'ai pas pu faire fonctionner le code de Brandrew pour tester DirectX via GetRenderTargetData. La copie d'écran est sortie purement noire. Cependant, il pourrait copier cet écran vierge très rapidement! Je continuerai à bricoler et j'espère obtenir une version fonctionnelle pour en voir les vrais résultats.
la source
GetRenderTargetData
approche fonctionne. J'écrirai peut-être ma propre réponse lorsque j'aurai terminé ma candidature. Ou, vous pouvez mettre à jour le vôtre une fois que tout fonctionne.Quelques choses que j'ai pu glaner: apparemment, utiliser un "pilote miroir" est rapide bien que je ne connaisse pas de pilote OSS.
Pourquoi RDP est-il si rapide par rapport à d'autres logiciels de contrôle à distance?
Apparemment, l'utilisation de certaines convolutions de StretchRect est plus rapide que BitBlt
http://betterlogic.com/roger/2010/07/fast-screen-capture/comment-page-1/#comment-5193
Et celui que vous avez mentionné (les fraps se connectant aux dll D3D) est probablement le seul moyen pour les applications D3D, mais ne fonctionnera pas avec la capture de bureau Windows XP. Alors maintenant, je souhaite juste qu'il y ait un équivalent de fraps en termes de vitesse pour les fenêtres de bureau normales ... n'importe qui?
(Je pense qu'avec aero, vous pourrez peut-être utiliser des crochets de type fraps, mais les utilisateurs de XP n'auraient pas de chance).
Changer apparemment également la profondeur de bits de l'écran et / ou désactiver l'accélération matérielle. peut aider (et / ou désactiver l'aéro).
https://github.com/rdp/screen-capture-recorder-program comprend un utilitaire de capture basé sur BitBlt raisonnablement rapide et un benchmark dans le cadre de son installation, qui peut vous permettre de comparer les vitesses BitBlt pour les optimiser.
VirtualDub a également un module de capture d'écran "opengl" qui est dit rapide et fait des choses comme la détection des changements http://www.virtualdub.org/blog/pivot/entry.php?id=290
la source
Pour C ++, vous pouvez utiliser: http://www.pinvoke.net/default.aspx/gdi32/BitBlt.html
Cela peut ne pas fonctionner sur tous les types d'applications 3D / applications vidéo. Ensuite, ce lien peut être plus utile car il décrit 3 méthodes différentes que vous pouvez utiliser.
Ancienne réponse (C #):
Vous pouvez utiliser System.Drawing.Graphics.Copy , mais ce n'est pas très rapide.
Un exemple de projet que j'ai écrit en faisant exactement ceci: http://blog.tedd.no/index.php/2010/08/16/c-image-analysis-auto-gaming-with-source/
Je prévois de mettre à jour cet exemple en utilisant une méthode plus rapide comme Direct3D: http://spazzarama.com/2009/02/07/screencapture-with-direct3d/
Et voici un lien pour capturer en vidéo: Comment capturer l'écran en vidéo en utilisant C # .Net?
la source
Avec Windows 8, Microsoft a introduit l'API de duplication du bureau Windows. C'est la manière officiellement recommandée de le faire. Une fonctionnalité intéressante pour la capture d'écran est qu'il détecte le mouvement de la fenêtre, vous pouvez donc transmettre des deltas de bloc lorsque les fenêtres sont déplacées, au lieu de pixels bruts. En outre, il vous indique quels rectangles ont changé, d'une image à l'autre.
L'exemple de code Microsoft est assez complexe, mais l'API est en fait simple et facile à utiliser. J'ai mis en place un exemple de projet qui est beaucoup plus simple que l'exemple officiel:
https://github.com/bmharper/WindowsDesktopDuplicationSample
Docs: https://docs.microsoft.com/en-gb/windows/desktop/direct3ddxgi/desktop-dup-api
Exemple de code officiel Microsoft: https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a
la source
Vous pouvez essayer le projet open source c ++ WinRobot @git , un puissant capteur d' écran
Soutien :
la source
Je le fais moi-même avec directx et je pense que c'est aussi rapide que vous le souhaiteriez. Je n'ai pas d'exemple de code rapide, mais j'ai trouvé cela qui devrait être utile. la version directx11 ne devrait pas différer beaucoup, directx9 peut-être un peu plus, mais c'est la voie à suivre
la source
Je me rends compte que la suggestion suivante ne répond pas à votre question, mais la méthode la plus simple que j'ai trouvée pour capturer une vue DirectX en évolution rapide est de brancher une caméra vidéo sur le port S-vidéo de la carte vidéo et d'enregistrer les images comme un film. Transférez ensuite la vidéo de l'appareil photo vers un fichier MPG, WMV, AVI, etc. sur l'ordinateur.
la source
L'enregistrement d'écran peut être effectué en C # à l' aide de l' API VLC . J'ai fait un exemple de programme pour le démontrer. Il utilise LibVLCSharp et VideoLAN.LibVLC.Windows bibliothèques . Vous pouvez obtenir de nombreuses autres fonctionnalités liées au rendu vidéo à l'aide de cette API multiplateforme.
Pour la documentation de l'API, voir: API LibVLCSharp Github
la source
Capture de bureau DXGI
Projet qui capture l'image du bureau avec duplication DXGI. Enregistre l'image capturée dans le fichier dans différents formats d'image (* .bmp; * .jpg; * .tif).
Cet exemple est écrit en C ++. Vous avez également besoin d'une certaine expérience avec DirectX (D3D11, D2D1).
Ce que l'application peut faire
la source