내 웹캠의 원시 픽셀 데이터에 액세스 할 수있는 코드가 있습니다. 그러나 이미지 너비, 높이, 픽셀 형식 및 선호하는 데이터 보폭 (피치, 메모리 패딩 또는 무엇이든 원하는 경우)을 알 필요가 있습니다. 픽셀 당 너비 * 바이트가 아닌 경우directshow 웹캠 비디오 스트림의 너비와 높이를 얻는 방법
#include <windows.h>
#include <dshow.h>
#pragma comment(lib,"Strmiids.lib")
#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no);\
*(INT_PTR*)&c##_=*p; VirtualProtect(p, 4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
// Here you get image video data in buf/len. Process it before calling Receive_ because renderer dealocates it.
HRESULT (__stdcall * Receive_) (void* inst, IMediaSample *smp) ;
HRESULT __stdcall Receive (void* inst, IMediaSample *smp) {
BYTE* buf; smp->GetPointer(&buf); DWORD len = smp->GetActualDataLength();
//AM_MEDIA_TYPE* info;
//smp->GetMediaType(&info);
HRESULT ret = Receive_ (inst, smp);
return ret;
}
int WINAPI WinMain(HINSTANCE inst,HINSTANCE prev,LPSTR cmd,int show){
HRESULT hr = CoInitialize(0); MSG msg={0}; DWORD no;
IGraphBuilder* graph= 0; hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph);
IMediaControl* ctrl = 0; hr = graph->QueryInterface(IID_IMediaControl, (void **)&ctrl);
ICreateDevEnum* devs = 0; hr = CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs);
IEnumMoniker* cams = 0; hr = devs?devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0):0;
IMoniker* mon = 0; hr = cams->Next (1,&mon,0); // get first found capture device (webcam?)
IBaseFilter* cam = 0; hr = mon->BindToObject(0,0,IID_IBaseFilter, (void**)&cam);
hr = graph->AddFilter(cam, L"Capture Source"); // add web cam to graph as source
IEnumPins* pins = 0; hr = cam?cam->EnumPins(&pins):0; // we need output pin to autogenerate rest of the graph
IPin* pin = 0; hr = pins?pins->Next(1,&pin, 0):0; // via graph->Render
hr = graph->Render(pin); // graph builder now builds whole filter chain including MJPG decompression on some webcams
IEnumFilters* fil = 0; hr = graph->EnumFilters(&fil); // from all newly added filters
IBaseFilter* rnd = 0; hr = fil->Next(1,&rnd,0); // we find last one (renderer)
hr = rnd->EnumPins(&pins); // because data we are intersted in are pumped to renderers input pin
hr = pins->Next(1,&pin, 0); // via Receive member of IMemInputPin interface
IMemInputPin* mem = 0; hr = pin->QueryInterface(IID_IMemInputPin,(void**)&mem);
DsHook(mem,6,Receive); // so we redirect it to our own proc to grab image data
hr = ctrl->Run();
while (GetMessage( &msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage( &msg);
}
};
이 물건을 창문으로 렌더링하지 말고 이미지 데이터에 접근 할 수있는 방법을 말해 준다면 보너스 포인트가 필요합니다.
하하하. 나는 코드가 너무 짧아서 좋지 않다고 생각했다. 나는 너의 다른 지위를 조사 할 것이다. –