Winapi 媒体基础捕捉反转图像

Winapi 媒体基础捕捉反转图像,winapi,ms-media-foundation,gdi,Winapi,Ms Media Foundation,Gdi,这有点奇怪,我正在用SourceReader从我的相机中捕获样本。我最终得到了一张倒置的HBITMAP 以下是捕获代码: for (;;) { DWORD streamIndex = 0, flags = 0; LONGLONG llTimeStamp = 0; CComPtr<IMFSample> pSample; hr = sr->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,0,&s

这有点奇怪,我正在用SourceReader从我的相机中捕获样本。我最终得到了一张倒置的HBITMAP

以下是捕获代码:

for (;;)
{
    DWORD streamIndex = 0, flags = 0;
    LONGLONG llTimeStamp = 0;
    CComPtr<IMFSample> pSample;

    hr = sr->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,0,&streamIndex,&flags,&llTimeStamp,&pSample);
...
}
捕获后,我转换IMFSample:

CComPtr<IMFSample> pSample2;
MFCreateSample(&pSample2);

if (si.cbSize == 0)
    prvtrs->GetOutputStreamInfo(oods[0], &si);

CComPtr<IMFMediaBuffer> bb;
MFCreateMemoryBuffer(si.cbSize, &bb);
pSample2->AddBuffer(bb);


hr = prvtrs->ProcessInput(iids[0], pSample, 0);
MFT_OUTPUT_DATA_BUFFER db = { 0 };
db.dwStreamID = oods[0];
db.pSample = pSample2;
DWORD st;
hr = prvtrs->ProcessOutput(0, 1, &db, &st);
if (db.pEvents)
    db.pEvents->Release();
if (SUCCEEDED(hr))
{
    // Show it
    CComPtr<IMFMediaBuffer> b4;
    pSample2->ConvertToContiguousBuffer(&b4);
    if (b4)
    {
        vector<char> o;
        auto bi = SaveSample(b4, wi, he);
....
CComPtr示例2;
MFCreateSample(&pSample2);
如果(si.cbSize==0)
prvtrs->GetOutputStreamInfo(oods[0],&si);
CComPtr bb;
MFCreateMemoryBuffer(si.cbSize和bb);
pSample2->AddBuffer(bb);
hr=prvtrs->ProcessInput(iids[0],示例,0);
MFT_输出_数据_缓冲区db={0};
db.dwStreamID=oods[0];
db.pSample=pSample2;
德沃德街;
hr=prvtrs->ProcessOutput(0、1、db和st);
如果(分贝事件)
db.pEvents->Release();
如果(成功(hr))
{
//表现出来
CComPtr b4;
示例2->转换到连续缓冲区(&b4);
如果(b4)
{
向量o;
自动bi=保存样本(b4、wi、he);
....
这是我的示例:

HBITMAP SaveSample(CComPtr<IMFMediaBuffer> mediaBuffer, int width32, int height32)
{
    HRESULT hr = 0;
    BYTE *pData = NULL;
    DWORD le = 0;
    mediaBuffer->GetCurrentLength(&le);
    hr = mediaBuffer->Lock(&pData, NULL, NULL);
    if (!pData)
        return 0;
    unsigned char*  pixels = pData;
    // at this point we have some input

    BITMAPINFOHEADER bmih;
    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biWidth = width32;
    bmih.biHeight = height32;
    bmih.biPlanes = 1;
    bmih.biBitCount = 32;
    bmih.biCompression = BI_RGB;
    bmih.biSizeImage = 0;
    bmih.biXPelsPerMeter = 0;
    bmih.biYPelsPerMeter = 0;
    bmih.biClrUsed = 0;
    bmih.biClrImportant = 0;

    BITMAPINFO dbmi = { 0 };
    dbmi.bmiHeader = bmih;
    dbmi.bmiColors->rgbBlue = 0;
    dbmi.bmiColors->rgbGreen = 0;
    dbmi.bmiColors->rgbRed = 0;
    dbmi.bmiColors->rgbReserved = 0;

    HDC hdc = ::GetDC(NULL);
    HBITMAP hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, pixels, &dbmi, DIB_RGB_COLORS);
    ::ReleaseDC(NULL, hdc);

    mediaBuffer->Unlock();
    return hbmp;
}
HBITMAP SaveSample(CComPtr mediaBuffer,int-width32,int-height32)
{
HRESULT hr=0;
字节*pData=NULL;
DWORD-le=0;
mediaBuffer->GetCurrentLength(&le);
hr=mediaBuffer->Lock(&pData,NULL,NULL);
如果(!pData)
返回0;
无符号字符*像素=pData;
//在这一点上,我们有一些投入
位图信息头;
bmih.biSize=sizeof(BitMapInfo头);
bmih.biWidth=width32;
bmih.biHeight=高度32;
双翼飞机=1;
bmih.bibibitcount=32;
bmih.biCompression=BI_RGB;
bmih.biSizeImage=0;
bmih.biXPelsPerMeter=0;
bmih.biYPelsPerMeter=0;
bmih.biClrUsed=0;
bmih.biclr=0;
BITMAPINFO dbmi={0};
dbmi.bmiHeader=bmih;
dbmi.bmiColors->rgbBlue=0;
dbmi.bmiColors->rgbGreen=0;
dbmi.bmiColors->rgbreed=0;
dbmi.bmiColors->rgbReserved=0;
HDC HDC=::GetDC(NULL);
HBITMAP hbmp=CreateDIBitmap(hdc、bmih、CBM_INIT、像素、dbmi、DIB_RGB_颜色);
::ReleaseDC(NULL,hdc);
mediaBuffer->Unlock();
返回hbmp;
}

我得到的是一个颠倒的位图。我做错了什么?

您错过了以下关键部分:

像素阵列是一个32位DWORD块,逐像素描述图像。通常像素存储为“自下而上”,从左下角开始,从左到右,然后从图像的底部到顶部逐行存储。[4]除非使用BITMAPCOREHEADER,否则当图像高度值为负值时,也可以从上到下存储未压缩的Windows位图

考虑到这一点,您可以轻松修复错误

HBITMAP SaveSample(CComPtr<IMFMediaBuffer> mediaBuffer, int width32, int height32)
{
    HRESULT hr = 0;
    BYTE *pData = NULL;
    DWORD le = 0;
    mediaBuffer->GetCurrentLength(&le);
    hr = mediaBuffer->Lock(&pData, NULL, NULL);
    if (!pData)
        return 0;
    unsigned char*  pixels = pData;
    // at this point we have some input

    BITMAPINFOHEADER bmih;
    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biWidth = width32;
    bmih.biHeight = height32;
    bmih.biPlanes = 1;
    bmih.biBitCount = 32;
    bmih.biCompression = BI_RGB;
    bmih.biSizeImage = 0;
    bmih.biXPelsPerMeter = 0;
    bmih.biYPelsPerMeter = 0;
    bmih.biClrUsed = 0;
    bmih.biClrImportant = 0;

    BITMAPINFO dbmi = { 0 };
    dbmi.bmiHeader = bmih;
    dbmi.bmiColors->rgbBlue = 0;
    dbmi.bmiColors->rgbGreen = 0;
    dbmi.bmiColors->rgbRed = 0;
    dbmi.bmiColors->rgbReserved = 0;

    HDC hdc = ::GetDC(NULL);
    HBITMAP hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, pixels, &dbmi, DIB_RGB_COLORS);
    ::ReleaseDC(NULL, hdc);

    mediaBuffer->Unlock();
    return hbmp;
}