李国帅 2015/3/27 10:46:31 在使用directshow进行抓图的时候,存在两难: 如果在转换过滤器抓图,那么可能因为某些原因无法抓到真实的图片。 如果使用directx的vmr9抓图,可能效率比较低,
李国帅 2015/3/27 10:46:31
在使用directshow进行抓图的时候,存在两难:
如果在转换过滤器抓图,那么可能因为某些原因无法抓到真实的图片。
如果使用directx的vmr9抓图,可能效率比较低,m_pVmrWC->GetCurrentImage(&pDataBuffer);//大概需要3秒钟
但现在也只能使用vmr抓图了。
#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;
}