Anonymous
Захват изображения с помощью Media Foundation
Сообщение
Anonymous » 09 янв 2025, 11:11
У меня возникла проблема при работе с Windows API и библиотекой Media Foundation. Код, который я привел ниже, захватывает и сохраняет изображение с веб-камеры, но полученное изображение черно-белое, и есть два изображения рядом. Может ли кто-нибудь мне помочь с этим?
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfreadwrite.lib")
#pragma comment(lib, "mf.lib")
const GUID MFVideoFormat_RGB32 = { 0x00000016, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} };
const GUID MF_MT_MAJOR_TYPE = { 0x48eba18e, 0xf8c9, 0x4687, {0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f} };
const GUID MF_MT_SUBTYPE = { 0xf7e34c9a, 0x42e8, 0x4714, {0xb7, 0x83, 0x5e, 0xbd, 0xa4, 0x3a, 0xe5, 0x04} };
const GUID MFMediaType_Video = { 0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} };
HRESULT InitializeMediaFoundation() {
HRESULT hr = MFStartup(MF_VERSION);
if (FAILED(hr)) {
printf("MFStartup failed: 0x%lx\n", hr);
}
return hr;
}
HRESULT CreateVideoDeviceSource(IMFMediaSource** ppSource) {
IMFAttributes* pAttributes = NULL;
IMFActivate** ppDevices = NULL;
UINT32 count = 0;
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
if (FAILED(hr)) {
printf("MFCreateAttributes failed: 0x%lx\n", hr);
return hr;
}
hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
if (FAILED(hr)) {
printf("SetGUID MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE failed: 0x%lx\n", hr);
pAttributes->Release();
return hr;
}
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (FAILED(hr)) {
printf("MFEnumDeviceSources failed: 0x%lx\n", hr);
pAttributes->Release();
return hr;
}
if (count > 0) {
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
if (FAILED(hr)) {
printf("ActivateObject failed: 0x%lx\n", hr);
}
}
else {
printf("No video capture devices found.\n");
hr = E_FAIL;
}
for (UINT32 i = 0; i < count; i++) {
ppDevices[i]->Release();
}
CoTaskMemFree(ppDevices);
pAttributes->Release();
return hr;
}
HRESULT CaptureImage() {
IMFMediaSource* pSource = NULL;
IMFSourceReader* pReader = NULL;
IMFMediaType* pType = NULL;
DWORD streamIndex = MF_SOURCE_READER_FIRST_VIDEO_STREAM;
HRESULT hr = CreateVideoDeviceSource(&pSource);
if (FAILED(hr)) {
return hr;
}
hr = MFCreateSourceReaderFromMediaSource(pSource, NULL, &pReader);
if (FAILED(hr)) {
printf("MFCreateSourceReaderFromMediaSource failed: 0x%lx\n", hr);
pSource->Release();
return hr;
}
hr = pReader->GetCurrentMediaType(streamIndex, &pType);
if (FAILED(hr)) {
printf("GetCurrentMediaType failed: 0x%lx\n", hr);
pReader->Release();
pSource->Release();
return hr;
}
hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
if (FAILED(hr)) {
printf("SetGUID MF_MT_SUBTYPE failed: 0x%lx\n", hr);
pType->Release();
pReader->Release();
pSource->Release();
return hr;
}
hr = pReader->SetCurrentMediaType(streamIndex, NULL, pType);
if (FAILED(hr)) {
printf("SetCurrentMediaType failed: 0x%lx\n", hr);
pType->Release();
pReader->Release();
pSource->Release();
return hr;
}
pType->Release();
IMFSample* pSample = NULL;
DWORD dwFlags = 0;
for (int i = 0; i < 10; ++i) {
hr = pReader->ReadSample(streamIndex, 0, NULL, &dwFlags, NULL, &pSample);
if (SUCCEEDED(hr) && pSample) {
break;
}
Sleep(100);
}
if (FAILED(hr) || !pSample) {
printf("ReadSample failed: 0x%lx\n", hr);
printf("Flags: 0x%lx\n", dwFlags); flags
pReader->Release();
pSource->Release();
return hr;
}
printf("Sample read successfully.\n");
IMFMediaBuffer* pBuffer = NULL;
hr = pSample->ConvertToContiguousBuffer(&pBuffer);
if (FAILED(hr)) {
printf("ConvertToContiguousBuffer failed: 0x%lx\n", hr);
pSample->Release();
pReader->Release();
pSource->Release();
return hr;
}
BYTE* pData = NULL;
DWORD cbBuffer = 0;
hr = pBuffer->Lock(&pData, NULL, &cbBuffer);
if (FAILED(hr)) {
printf("Lock failed: 0x%lx\n", hr);
pBuffer->Release();
pSample->Release();
pReader->Release();
pSource->Release();
return hr;
}
const char* filePath = "C:\\capture.bmp";
FILE* pFile;
fopen_s(&pFile, filePath, "wb");
if (pFile) {
BITMAPFILEHEADER bfHeader;
BITMAPINFOHEADER biHeader;
bfHeader.bfType = 'MB';
bfHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cbBuffer;
bfHeader.bfReserved1 = 0;
bfHeader.bfReserved2 = 0;
bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
biHeader.biSize = sizeof(BITMAPINFOHEADER);
biHeader.biWidth = 640;
biHeader.biHeight = -480;
biHeader.biPlanes = 1;
biHeader.biBitCount = 32;
biHeader.biCompression = BI_RGB;
biHeader.biSizeImage = cbBuffer;
biHeader.biXPelsPerMeter = 0;
biHeader.biYPelsPerMeter = 0;
biHeader.biClrUsed = 0;
biHeader.biClrImportant = 0;
fwrite(&bfHeader, sizeof(BITMAPFILEHEADER), 1, pFile);
fwrite(&biHeader, sizeof(BITMAPINFOHEADER), 1, pFile);
fwrite(pData, cbBuffer, 1, pFile);
fclose(pFile);
printf("Image saved to %s\n", filePath);
}
else {
printf("Failed to open file for writing\n");
}
hr = pBuffer->Unlock();
pBuffer->Release();
if (pSample) {
pSample->Release();
}
if (pReader) {
pReader->Release();
}
if (pSource) {
pSource->Release();
}
return hr;
}
int main() {
HRESULT hr = InitializeMediaFoundation();
if (SUCCEEDED(hr)) {
hr = CaptureImage();
if (SUCCEEDED(hr)) {
printf("Image captured successfully.\n");
}
else {
printf("Failed to capture image: 0x%lx\n", hr);
}
}
MFShutdown();
return 0;
}
вот один пример изображения
Я использую Visual Studio 2022. Это программа, которая захватывает изображение с веб-камеры и сохраняет его на диск C.
Подробнее здесь:
https://stackoverflow.com/questions/793 ... foundation
1736410311
Anonymous
У меня возникла проблема при работе с Windows API и библиотекой Media Foundation. Код, который я привел ниже, захватывает и сохраняет изображение с веб-камеры, но полученное изображение черно-белое, и есть два изображения рядом. Может ли кто-нибудь мне помочь с этим? [code]#include #include #include #include #include #include #include #pragma comment(lib, "mfplat.lib") #pragma comment(lib, "mfreadwrite.lib") #pragma comment(lib, "mf.lib") const GUID MFVideoFormat_RGB32 = { 0x00000016, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} }; const GUID MF_MT_MAJOR_TYPE = { 0x48eba18e, 0xf8c9, 0x4687, {0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f} }; const GUID MF_MT_SUBTYPE = { 0xf7e34c9a, 0x42e8, 0x4714, {0xb7, 0x83, 0x5e, 0xbd, 0xa4, 0x3a, 0xe5, 0x04} }; const GUID MFMediaType_Video = { 0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} }; HRESULT InitializeMediaFoundation() { HRESULT hr = MFStartup(MF_VERSION); if (FAILED(hr)) { printf("MFStartup failed: 0x%lx\n", hr); } return hr; } HRESULT CreateVideoDeviceSource(IMFMediaSource** ppSource) { IMFAttributes* pAttributes = NULL; IMFActivate** ppDevices = NULL; UINT32 count = 0; HRESULT hr = MFCreateAttributes(&pAttributes, 1); if (FAILED(hr)) { printf("MFCreateAttributes failed: 0x%lx\n", hr); return hr; } hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); if (FAILED(hr)) { printf("SetGUID MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE failed: 0x%lx\n", hr); pAttributes->Release(); return hr; } hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); if (FAILED(hr)) { printf("MFEnumDeviceSources failed: 0x%lx\n", hr); pAttributes->Release(); return hr; } if (count > 0) { hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource)); if (FAILED(hr)) { printf("ActivateObject failed: 0x%lx\n", hr); } } else { printf("No video capture devices found.\n"); hr = E_FAIL; } for (UINT32 i = 0; i < count; i++) { ppDevices[i]->Release(); } CoTaskMemFree(ppDevices); pAttributes->Release(); return hr; } HRESULT CaptureImage() { IMFMediaSource* pSource = NULL; IMFSourceReader* pReader = NULL; IMFMediaType* pType = NULL; DWORD streamIndex = MF_SOURCE_READER_FIRST_VIDEO_STREAM; HRESULT hr = CreateVideoDeviceSource(&pSource); if (FAILED(hr)) { return hr; } hr = MFCreateSourceReaderFromMediaSource(pSource, NULL, &pReader); if (FAILED(hr)) { printf("MFCreateSourceReaderFromMediaSource failed: 0x%lx\n", hr); pSource->Release(); return hr; } hr = pReader->GetCurrentMediaType(streamIndex, &pType); if (FAILED(hr)) { printf("GetCurrentMediaType failed: 0x%lx\n", hr); pReader->Release(); pSource->Release(); return hr; } hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); if (FAILED(hr)) { printf("SetGUID MF_MT_SUBTYPE failed: 0x%lx\n", hr); pType->Release(); pReader->Release(); pSource->Release(); return hr; } hr = pReader->SetCurrentMediaType(streamIndex, NULL, pType); if (FAILED(hr)) { printf("SetCurrentMediaType failed: 0x%lx\n", hr); pType->Release(); pReader->Release(); pSource->Release(); return hr; } pType->Release(); IMFSample* pSample = NULL; DWORD dwFlags = 0; for (int i = 0; i < 10; ++i) { hr = pReader->ReadSample(streamIndex, 0, NULL, &dwFlags, NULL, &pSample); if (SUCCEEDED(hr) && pSample) { break; } Sleep(100); } if (FAILED(hr) || !pSample) { printf("ReadSample failed: 0x%lx\n", hr); printf("Flags: 0x%lx\n", dwFlags); flags pReader->Release(); pSource->Release(); return hr; } printf("Sample read successfully.\n"); IMFMediaBuffer* pBuffer = NULL; hr = pSample->ConvertToContiguousBuffer(&pBuffer); if (FAILED(hr)) { printf("ConvertToContiguousBuffer failed: 0x%lx\n", hr); pSample->Release(); pReader->Release(); pSource->Release(); return hr; } BYTE* pData = NULL; DWORD cbBuffer = 0; hr = pBuffer->Lock(&pData, NULL, &cbBuffer); if (FAILED(hr)) { printf("Lock failed: 0x%lx\n", hr); pBuffer->Release(); pSample->Release(); pReader->Release(); pSource->Release(); return hr; } const char* filePath = "C:\\capture.bmp"; FILE* pFile; fopen_s(&pFile, filePath, "wb"); if (pFile) { BITMAPFILEHEADER bfHeader; BITMAPINFOHEADER biHeader; bfHeader.bfType = 'MB'; bfHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cbBuffer; bfHeader.bfReserved1 = 0; bfHeader.bfReserved2 = 0; bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); biHeader.biSize = sizeof(BITMAPINFOHEADER); biHeader.biWidth = 640; biHeader.biHeight = -480; biHeader.biPlanes = 1; biHeader.biBitCount = 32; biHeader.biCompression = BI_RGB; biHeader.biSizeImage = cbBuffer; biHeader.biXPelsPerMeter = 0; biHeader.biYPelsPerMeter = 0; biHeader.biClrUsed = 0; biHeader.biClrImportant = 0; fwrite(&bfHeader, sizeof(BITMAPFILEHEADER), 1, pFile); fwrite(&biHeader, sizeof(BITMAPINFOHEADER), 1, pFile); fwrite(pData, cbBuffer, 1, pFile); fclose(pFile); printf("Image saved to %s\n", filePath); } else { printf("Failed to open file for writing\n"); } hr = pBuffer->Unlock(); pBuffer->Release(); if (pSample) { pSample->Release(); } if (pReader) { pReader->Release(); } if (pSource) { pSource->Release(); } return hr; } int main() { HRESULT hr = InitializeMediaFoundation(); if (SUCCEEDED(hr)) { hr = CaptureImage(); if (SUCCEEDED(hr)) { printf("Image captured successfully.\n"); } else { printf("Failed to capture image: 0x%lx\n", hr); } } MFShutdown(); return 0; } [/code] вот один пример изображения [img]https://i.sstatic.net/ bkWHnqUr.png[/img] Я использую Visual Studio 2022. Это программа, которая захватывает изображение с веб-камеры и сохраняет его на диск C. Подробнее здесь: [url]https://stackoverflow.com/questions/79312169/capturing-an-image-using-media-foundation[/url]