首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

请教这段实现视频渐隐渐显的代码有什么有关问题

2012-01-06 
请问这段实现视频渐隐渐显的代码有什么问题?这是我的filter中的一个渐隐的函数,其中p是一帧帧的视频数据流

请问这段实现视频渐隐渐显的代码有什么问题?
这是我的filter中的一个渐隐的函数,其中p是一帧帧的视频数据流,cx、cy是宽高。(因为是24位,所以不用alpha通道实现)
现在的问题是:显示原图像,然后等待100MS后直接变黑色,没有渐变。
我的分析是:视频数据流的颜色没有随prgbSrc实时改变,而是取了prgbSrc的最终值。


bool FadeOut(BYTE* p, int cx, int cy)
{
BOOL bDraw = FALSE;
int r,g,b;

RGBTRIPLE *prgbSrc =(RGBTRIPLE*)p;

while(!bDraw)
{
bDraw=TRUE; 
for(int j=0; j<cy; j++)
{
for(int i=0; i<cx; i++)
{
r=prgbSrc[i+j*cx].rgbtRed;
g=prgbSrc[i+j*cx].rgbtGreen;
b=prgbSrc[i+j*cx].rgbtBlue;

r=r-10>0?r-10:0;
g=g-10>0?g-10:0;
b=b-10>0?b-10:0;

prgbSrc[i+j*cx].rgbtRed = (BYTE)r;
prgbSrc[i+j*cx].rgbtGreen = (BYTE)g;
prgbSrc[i+j*cx].rgbtBlue = (BYTE)b;

if((r>0)||(g>0)||(b>0))
bDraw=FALSE;
}
}
  ///觉得这里应该加什么代码来实时保存prgbSrc,不知对不对?
Sleep(100);
}
return true;
}

[解决办法]
if((r> 0) ¦ ¦(g> 0) ¦ ¦(b> 0)) 
bDraw=FALSE; 
你的这句不知道是干什么的,不行就把这句去掉,应该就可以了。
[解决办法]
是一帧,但一帧比一帧暗。
[解决办法]
bool FadeOut(BYTE* p, int cx, int cy) 

BOOL bDraw = FALSE; 
int r,g,b; 

RGBTRIPLE *prgbSrc =(RGBTRIPLE*)p; 

while(!bDraw) 

bDraw=TRUE;
for(int j=0; j <cy; j++) 

for(int i=0; i <cx; i++) 
{ //从图象(0,0)点开始处理[/color]
r=prgbSrc[i+j*cx].rgbtRed; 
g=prgbSrc[i+j*cx].rgbtGreen; 
b=prgbSrc[i+j*cx].rgbtBlue; 

r=r-10> 0?r-10:0; //对一帧图象的一点R G B 三个通道 值减10和0判断 
g=g-10> 0?g-10:0; 
b=b-10> 0?b-10:0; 

prgbSrc[i+j*cx].rgbtRed = (BYTE)r; 
prgbSrc[i+j*cx].rgbtGreen = (BYTE)g; 
prgbSrc[i+j*cx].rgbtBlue = (BYTE)b; 

if((r> 0) ¦ ¦(g> 0) ¦ ¦(b> 0)) 
bDraw=FALSE; 


也就是说你这一帧图象处理完了之后 很有可能是每1个象素点RGB都减了10 (假设没有点的RGB三个值均小于10的情况)
下一帧重新读如然后相同处理.......

个人感觉:如果你要实现渐变 那个10不应该是固定的 应该是动态增加的,而且要保存.....
处理完了后 第二次看这个视频的时候视频会出现渐变.
wuchuncai那个 用动态Val的是对的 每帧val += 10;(每帧多减一个10)

 你那个代码对同一副图象的反复读入应该就可以实现简便效果的
 前提是你每一个点RGB都大于10 如果有一个点是(5,4,4)那么处理后都变成0
 那么if((r> 0) ¦ ¦(g> 0) ¦ ¦(b> 0)) 
bDraw=FALSE; //不起作用了
 之后就不进入WHILE
[解决办法]
昨天捡了张光盘,里面有个浅显的部分

C/C++ code
/*渐显特效显示*/void CDynSplitView2::OnJianxian() {    //刷新屏幕    CDC *pDC=GetDC();    CRect rect(0,0,1000,1000);    CBrush brush(RGB(255,255,255));            pDC->FillRect(&rect,&brush);    //复制图像数据    clearmem();    CDSplitDoc* pDoc = GetDocument();    ASSERT_VALID(pDoc);    if(!pDoc ->statedoc&&state2==1 )    {        BYTE* pBitmapData = CDibNew1->GetData();        LPBITMAPINFO pBitmapInfo = CDibNew1->GetInfo();        int bitmapHeight= CDibNew1->GetHeight();        int bitmapWidth = CDibNew1->GetWidth();        if (CDibNew1->GetRGB()) // Has a color table        {            CPalette * hPalette=CreateBitmapPalette(CDibNew1);            CPalette * hOldPalette = pDC->SelectPalette(hPalette, true);            pDC->RealizePalette();            LPBYTE temp,temp1,temp2;            temp=new BYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()];            memset (temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth());            for(int n=0;n<=256;n++)            {                temp1=temp;                temp2=pBitmapData;                for(int j = 0; j < bitmapHeight; j++)                {                    for(int i = 0; i < bitmapWidth; i ++)                    {                        *temp1=(*temp2)*(n)/256;                        temp1++;                        temp2++;                    }                }                ::StretchDIBits(pDC->GetSafeHdc(),0, 0, bitmapWidth, bitmapHeight,                    0, 0, bitmapWidth, bitmapHeight,                    temp,pBitmapInfo,                    DIB_RGB_COLORS, SRCCOPY);                Sleep(10);                }            pDC->SelectPalette(hOldPalette, true);            ::DeleteObject(hPalette);            delete temp;        }         else        {            LPBYTE temp;            temp=new BYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()*3];            memset (temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);            for(int m=0;m<256;m++)            {                for(int j = 0; j < bitmapHeight; j++)                {                    for(int i = 0; i < bitmapWidth; i ++)                    {                        temp[j*bitmapWidth*3+i*3]=pBitmapData[j*bitmapWidth*3+i*3]*(m)/256;                        temp[j*bitmapWidth*3+i*3+1]=pBitmapData[j*bitmapWidth*3+i*3+1]*(m)/256;                        temp[j*bitmapWidth*3+i*3+2]=pBitmapData[j*bitmapWidth*3+i*3+2]*(m)/256;                    }                }                ::StretchDIBits(pDC->GetSafeHdc(),                    0, 0, bitmapWidth, bitmapHeight,                    0, 0, bitmapWidth, bitmapHeight,                    temp, pBitmapInfo,                    DIB_RGB_COLORS, SRCCOPY);                Sleep(20);            }            delete temp;        }    }} 


[解决办法]
虽然没有做过directshow的filter开发,但可以想象:

1、如果filter与Video Render 是共享一帧视频数据内存的(在这里就是传入的参数BYTE* p),那么在你的FILTER处理完一次后也应该有个通信机制,让Video Render 显示处理完的一帧,而不是要等到FILTER返回之后才显示。FILTER返回之后才显示,那么你永远只能够显示最后一次处理的结果;

2、如果FILTER接管了Video Render 的缓存(即Video Render 是直接从FILTER的输出中取数据显示的),那么在你的FILTER接收了一帧数据之后,应该连续输出N帧,也就是你Sleep(100)处的语句应该变成向Video Render 缓存中输出一帧的语句。这时也就是:USB视频设备(一帧数据)-> Filter->(渐变的N帧数据) Video Render 

[解决办法]
要进行实施显示才可

Sleep(100); 
///add 
Display(prgbSrc);

热点排行