2012-10-12 14 views
5

काम नहीं करता है क्योंकि D3DPOOL_SCRATCH द्वारा प्रोसेसिंग धीमी थी, मैंने इंटरनेट पर रिपोर्ट के संदर्भ में डेस्कटॉप कैप्चर प्रोग्राम लिखा था। हालांकि, परिणाम एक पिच-ब्लैक पिक्चर है। क्या यह एक कंसोल प्रोग्राम का परिणाम है या क्या कोई अन्य कारण है?डायरेक्टएक्स के साथ डेस्कटॉप कैप्चर

#include <stdio.h> 
#include <Windows.h> 
#include <d3d9.h> 

void main() 
{ 
    CoInitialize(NULL); 

    LPDIRECT3D9 d3d9; 
    LPDIRECT3DDEVICE9 d3ddev; 
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION); 

    int ww = GetSystemMetrics(SM_CXSCREEN); 
    int wh = GetSystemMetrics(SM_CYSCREEN); 

    HWND hwnd = GetDesktopWindow(); 
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 
    d3dpp.BackBufferCount = 1; 
    d3dpp.BackBufferWidth = ww; 
    d3dpp.BackBufferHeight = wh; 
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 
    d3dpp.MultiSampleQuality = 0; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    d3dpp.hDeviceWindow = hwnd; 
    d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 

    d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); 

    IDirect3DSurface9* render; 
    IDirect3DSurface9* dest; 
    d3ddev->CreateOffscreenPlainSurface(ww, wh, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &dest, NULL); 
    d3ddev->GetRenderTarget(0, &render); 
    d3ddev->GetRenderTargetData(render, dest); 

    D3DLOCKED_RECT bits; 
    dest->LockRect(&bits, NULL, D3DLOCK_READONLY); 

    // If a capture is successful, colors other than black(0x00000000) should enter. 
    for(int i = 0; i < 100; i++){ 
     printf("%02X ", *((BYTE*)bits.pBits + i)); 
    } 

    dest->UnlockRect(); 

    render->Release(); 
    dest->Release(); 
    d3ddev->Release(); 
    d3d9->Release(); 

    CoUninitialize(); 
} 
+0

मैंने आपका कोड चलाने का प्रयास किया। मुझे निम्न त्रुटियां मिलीं: 1> Source.obj: त्रुटि LNK2019: अनन्य बाहरी प्रतीक _Direct3DCreate9 @ 4 फ़ंक्शन में संदर्भित _main 1> MSVCRTD.lib (crtexew.obj): त्रुटि LNK2019: अनसुलझा बाहरी प्रतीक _WinMain @ 16 फ़ंक्शन में संदर्भित ___tmainCRTStartup मुझे समझ में नहीं आता कि उनका क्या मतलब है। मैं डायरेक्टएक्स में नया हूं और स्क्रीन कैप्चर प्रोग्राम बनाने की कोशिश कर रहा हूं। क्या आप मेरी मदद कर सकते हैं कि मैं कहां गलत हो रहा हूं या मुझे किस दिशा में जाना चाहिए? – newbie2015

उत्तर

5

यह आवेदन प्रकार से संबंधित कुछ भी नहीं है, तो आप डेस्कटॉप छवि के डेटा प्राप्त करना चाहते हैं, तो आपको निम्न समारोह

GetFrontBufferData

का उपयोग करना चाहिए तो बजाय बुला

d3ddev->GetRenderTarget(0, &render); 
d3ddev->GetRenderTargetData(render, dest); 

आपको

पर कॉल करना चाहिए
+0

लेकिन, प्रश्न शीर्षक ने डेस्कटॉप कैप्चर किया, मुझे लगता है कि आपको अपने अनुरोध से मेल खाने के लिए शीर्षक बदलना चाहिए और वीडियो कैप्चर के लिए डायरेक्टशो पर जाना चाहिए। – zdd

+0

क्या डायरेक्टशो द्वारा डेस्कटॉप के स्क्रीन शॉट को प्राप्त किया जा सकता है? – Tank2005

+0

यदि आप ओवरले सतह के साथ खेले गए लाइव वीडियो को कैप्चर करते हैं, तो आपको कुछ भी नहीं मिलेगा, क्योंकि ओवरले सतह को आम प्रौद्योगिकियों द्वारा कैद नहीं किया जा सकता है। आपको कुछ हुक की ज़रूरत है, यह वही है जो मैं ढूंढ रहा हूं। – zdd

4

यदि आप विंडोज 8 से पहले विंडोज के संस्करण पर चल रहे हैं, तो GetFrontBufferData API ठीक काम करता है, जैसा कि किसी अन्य उत्तर द्वारा दिया गया है। हालांकि, विंडोज 8 से शुरू होने पर, एक नया desktop duplication API है जिसका उपयोग वीडियो कर्सर में डेस्कटॉप कैप्चर करने के लिए किया जा सकता है, जिसमें माउस कर्सर परिवर्तन और स्क्रीन के कौन से हिस्से वास्तव में बदल गए या स्थानांतरित हो गए। यह डी 3 डी 9 दृष्टिकोण से कहीं अधिक प्रदर्शनकारी है और वीडियो स्ट्रीम में डेस्कटॉप एन्कोड करने जैसी चीज़ों को करने के लिए वास्तव में उपयुक्त है, क्योंकि आपको कभी भी GPU स्मृति से बनावट खींचना नहीं पड़ता है। नई एपीआई डीएक्सजीआई आउटपुट को समझाकर और उस स्क्रीन पर DuplicateOutput पर कॉल करके उपलब्ध है जिसे आप कैप्चर करना चाहते हैं। फिर आप उस लूप को दर्ज कर सकते हैं जो स्क्रीन को अपडेट करने और बदले में प्रत्येक फ्रेम को प्राप्त करने के लिए प्रतीक्षा करता है।

यदि आप किसी वीडियो में फ़्रेम को एन्कोड करना चाहते हैं, तो मैं डायरेक्टशो की बजाय Media Foundation पर एक नज़र डालने की अनुशंसा करता हूं, क्योंकि मीडिया फाउंडेशन के पास बहुत बेहतर प्रदर्शन है और एन्कोडिंग करने के लिए डी 3 डी 9 के बजाय डी 3 डी 11 का उपयोग कर सकता है। यह आपके परिदृश्य के आधार पर उपयोग करने में थोड़ा आसान है। वीडियो फ्रेम एन्कोडिंग की सबसे सरल विधि के लिए मीडिया फाउंडेशन के Sink Writer पर एक नज़र डालें।

पूर्ण प्रकटीकरण के लिए, मैं उस टीम पर काम करता हूं जो माइक्रोसॉफ्ट में डेस्कटॉप डुप्लिकेशन एपीआई का मालिक है, और मैंने व्यक्तिगत रूप से ऐसे ऐप्स लिखे हैं जो डेस्कटॉप फ़ाइल (और वीडियो, गेम्स इत्यादि) को 60fps पर वीडियो फ़ाइल में कैप्चर करते हैं तकनीक, साथ ही साथ कई अन्य परिदृश्य भी।

संबंधित मुद्दे