在BasicWindow中GetCurrentImage方法使用要注意的两个问题:
1、在建立filter graph是,我们renderer某个源时,系统默认采用video renderer,此时如果调用GetCurrentImage方法,并不可靠,有时甚至不能抓拍到;解决此问题 可以采用“Directshow实务精选”中提供的抓拍Filter来实现抓拍;但看够文章的人都知道比较复杂,其实有个比较简单的方法,就是直接用Video Mix renderer9代替Video Renderer:在renderer之前,把VMR9调到filter graph中即可。
2、另外,通常提供的例程回事这样的:
bool CDXGraph::SnapshotBitmap(const char*outFile)
{
if(mBasicVideo)
{
long bitmapSize=0;
if(SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize,0)))
{
bool pass=false;
//this->Pause;
BYTE*buffer=new BYTE[bitmapSize];
if(SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize,(long*)buffer)))
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
lpbi=(LPBITMAPINFOHEADER)buffer;
int nColors=1<<lpbi->biBitCount;
if(nColors>256)
nColors=0;
hdr.bfType=((WORD)('M'<<8|'B')); //always is "BM"
hdr.bfSize=bitmapSize+sizeof(hdr);
hdr.bfReserved1=0;
hdr.bfReserved2=0;
hdr.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+lpbi->biSize+nColors*sizeof(RGBQUAD));
CFile bmpFile(outFile,CFile::modeReadWrite|CFile::modeCreate|CFile::typeBinary);
bmpFile.Write(&hdr,sizeof(BITMAPFILEHEADER));
bmpFile.Write(buffer,bitmapSize);
bmpFile.Close();
pass=true;
}
delete buffer;
return pass;
}
}
return false;
}
大多时候,抓拍下来的图片都不能正常显示,其实也就是在写Bmp文件头是对图像位数处理不对引起的:
注意到变量nColor会直接影响到数据指示的位置,事实上GutCurrentImage并不支持带调色板的位图,所以可以改成这样
原来的代码:
int nColors=1<<lpbi->biBitCount;
if(nColors>256)
nColors=0;
改成:
int nColors=0;
if(lpbi->biBitCount<=8)
{
nColors=1<<lpbi->biBitCount;
}
这样图片浏览器再进行读取时就不会出错,
这样基本上能显示抓拍的图片