vc中有时会需要提取swf文件中的数据用于处理,由于swf文件要播放的内容会牵涉到as语言,Flash player是一个解释器,它能解析swf文件中的as脚本,所以在vc中,我们很难实现自己去显示swf中的图像。
这时我们要用到flash控件,这是一个COM组件,在对话框界面右键选择——插入ActiveX控件——选择Shockwave Flash Object,选中这个条目,会显示它的安装路径,如下图:
1-1 Flash控件
这样我们就插入一个flash控件,当我们双击这个条目时,就插入一个Flash控件了。双击flash空间窗口就能创建一个flash控件类,里面都是COM借口函数。声明一个flash控件变量就能使用了,
例如CShockwaveFlash m_FlashCtl;
1. 加载swf文件:
m_FlashCtl.LoadMovie(0, “1.swf”);
第一个参数:表示图像层数,层数值大的在上面显示;
第二个参数:swf图像的路径,可以是本地的,也可以是一个url。
2. 播放swf文件:
当文件加载以后就可以使用m_FlashCtl.Play(),进行播放了。
3. 跳转到某一帧:
m_FlashCtl.GotoFrame(index);
4. Flash图像的显示模式:
m_FlashCtl.putScaleMode(2);
2为拉伸图像适应窗口,就是保证不会出现黑边的现象。
我们提取swf图像的数据,主要用的就是这个函数,这个函数能保证我们把swf文件中的每一帧数据都提取,不会出现丢数据的现象。
介绍完怎样播放swf文件后,我们就需要把Flash控件中图像提取出来,使用是抓图技术,就是通常的屏幕抓图功能,主要使用双缓冲绘图(详细的双缓冲技术,我会专门有讲述的):
首先:得到显示图像的绘图设备:
CDC *pFlashDC = GetDlgItem(IDC_FLASHCTL)->GetWindowDC();
pDC中保存着swf图像,下面我们使用双缓冲把数据提取出来,建立一个内存绘图设备:
CDC memDC;
memDC.CreateCompatibleDC(pFlashDC);
兼容绘图设备有了,我们需要一个”绘图纸”,保存绘的图像,图纸的大小以flash控件的窗口为准:
CRect rect;
GetDlgItem(IDC_FLASHCTL)->GetWindowRect(rect);
// 得到flash控件窗口的宽和高
int width = rect.GetWidth();
int height = rect.GetHeight();
CBitmap memBit;
memBit.CreateCompatibleBitmap(pFlashDC, width, height);
// 选进设备
memDC.SelectObject(&memBit);
然后,我们只需把图绘在这个图纸上就行了
memDC.BitBlt(0, 0, width, height, pFlashDC, 0, 0, SRCCOPY);
这时memBit已经保存swf图像的数据了,下面使用memBit.GetBitmapBits(..)就能得到rgb32数据了。
PS:这里有几点需要注意:
1. 这种抓图技术的缺点是,当flash控件窗口被覆盖以后,再抓取的图像不是swf图像数据了,而是覆盖flash窗口的那个窗口的图像;
2. 有的swf只有一帧,但是却有很多帧图像,比如用as控制的脚本,这时你无法正确的得到swf文件的总帧数:
如:flash场景中有一个ball影片剪辑,这个swf文件只有一帧,在这一帧中加入如下脚本:
function MoveBall()
{
ball.x += 10;
}
SetInterval(MoveBall, 40);
以上的swf虽然只有一帧,却是个无限循环,所以你无法得到总帧数。