Захват изображения с помощью Media FoundationC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Захват изображения с помощью Media Foundation

Сообщение Anonymous »

У меня возникла проблема при работе с 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»