使用directx的vmr9抓图(jpg)

李国帅 2015/3/27 10:46:31

在使用directshow进行抓图的时候,存在两难:

如果在转换过滤器抓图,那么可能因为某些原因无法抓到真实的图片。

如果使用directx的vmr9抓图,可能效率比较低,m_pVmrWC->GetCurrentImage(&pDataBuffer);//大概需要3秒钟

但现在也只能使用vmr抓图了。



#include <Gdiplus.h>
#include <GdiplusHeaders.h>
#include <GdiplusImaging.h>
#pragma comment(lib,"gdiplus.lib.")
using namespace Gdiplus;
LONG VMR9::TakeSnapshot(LPCTSTR outFile)
{
    //CNetLog::printlog(0,_T("%s begin.\n"),__FUNCTIONT__);

    CheckPointer(m_pVmrWC, E_POINTER);

    BYTE *pDataBuffer = NULL;

    HRESULT hr = m_pVmrWC->GetCurrentImage(&pDataBuffer);//大概需要3秒钟
    BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)pDataBuffer;
    if (!SUCCEEDED(hr))
    {
        CNetLog::printlog(0, _T("%s TakeSnapshot failed.\n"), __FUNCTIONT__);
        return S_FALSE;
    }

    LONG nRet = SavePicture(outFile, lpbi, pDataBuffer);

    CoTaskMemFree(pDataBuffer);//释放资源
    return nRet;
}

LONG CVideoRenderer::SavePicture(LPCTSTR outFile, BITMAPINFOHEADER * lpbi, BYTE * pDataBuffer)
{
    LONG nRet = 0;
    int nColors = 1 << lpbi->biBitCount;
    if (nColors > 256)nColors = 0;

    DWORD    dwBitmapSize = 0;
    dwBitmapSize = nColors * sizeof(RGBQUAD)+lpbi->biSizeImage;//biSizeImage中包含 sizeof(BITMAPINFOHEADER)

    DWORD bOffBits = lpbi->biSize + nColors * sizeof(RGBQUAD);

    BITMAPFILEHEADER hdrFile;
    hdrFile.bfType = ((WORD)('M' << 8) | 'B'); // always is "BM"
    hdrFile.bfSize = sizeof(BITMAPFILEHEADER)+dwBitmapSize;
    hdrFile.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER)+bOffBits);
    hdrFile.bfReserved1 = 0;
    hdrFile.bfReserved2 = 0;

    CLSID clsid;//图像存储 jpg
    GetCodecClsid(L"image/jpeg", &clsid);
    //TCHAR* JpgFile = _T("e:\\test.jpg");//添加扩展名
    void* pbmpData = pDataBuffer + sizeof(BITMAPINFOHEADER)+nColors * sizeof(RGBQUAD);
    Bitmap *pBmp = Bitmap::FromBITMAPINFO((BITMAPINFO*)pDataBuffer, pbmpData);
    nRet = pBmp->Save(outFile, &clsid);

    CNetLog::printlog(0, _T("%s OK. ImgFile=%s\n"), __FUNCTIONT__, outFile);
    return nRet;
}

void CVideoRenderer::GetCodecClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  codenum = 0;
    UINT  size = 0;
    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
    GetImageEncodersSize(&codenum, &size);
    if (size == 0)
        return;
    pImageCodecInfo = new ImageCodecInfo[size];

    if (pImageCodecInfo == NULL)
        return;
    GetImageEncoders(codenum, size, pImageCodecInfo);
    for (UINT j = 0; j < codenum; ++j)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            delete[]pImageCodecInfo;
            return;
        }
    }
    delete[]pImageCodecInfo;
    return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微澜-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值