--“动画截图工具”系列开发纪实
作者:马健
邮箱:stronghorse@163.net
主页:http://stronghorse.yeah.net
不知道爱美是不是真的是人的一种天性,从我开始看动画起,每次看到豪华、Q感的画面,我都会忍不住想截下来永久保存。最开始我看的动画只有VCD,当然就是直接用超级解霸进行录像,用Photoshop进行放大。但在尝试过几次后,我发现存在以下问题:
这些问题指望靠超级解霸或Photoshop的升级来加以解决似乎不太现实,毕竟这不是他们的主打方向。因此我开始考虑开发自己的截图软件--Mpeg2Jpeg。
Mpeg2Jpeg的最初版本是基于Dongge Li 和 Ishwar K. Sethi开发的MDC库,能够逐帧解码原始VCD文件,保存成BMP或JPG。在放大方面,最早采用的是ComicsEnhancer Pro的图像处理内核,效果嘛……嘿嘿,和Photoshop差不多啦。后来在网上找到Intel公司免费发布的Intel Image Processing Library (IPL),放大效果虽然比Photoshop强,但是由于原始图片本身质量的问题,所以放大后的图像质量还是不能令人满意。
图像质量的问题曾经困扰了我很长时间,但是最终解决方案的获得却很是无心:一次我到清华去找动漫进行时老大clear,去早了他不在,我只好到清华书店去翻书杀时间。无意中在一本《数字图像处理》教材上看到用平均法去除噪声的说明,一下子茅塞顿开,冲回来后花20分钟搞定代码,运行……第一张图像一出来,我才看了一眼就激动到全身打抖!
此后没多久,最终版的Mpeg2Jpeg就在我的网站上正式发表。但是也正是在这时,先是RM、后是AVI的各种MPEG4压缩版动画片开始大行其道,Mpeg2Jpeg的作用开始减弱。
在RM刚开始流行的时候,我就开始考虑它的解码问题。但是RM文件格式一直没有公布,当时唯一能够得到的解码工具就是RealPlayer提供的ActiveX控件(SDK的发表是后来的事,而且SDK调用的解码内核也是这个控件提供的)。使用这个控件的源码可以从提供在线播放的网页上找到,也有人在CSDN上贴过在Delphi中使用这个控件的源码。但是奇怪的是,这个控件不能在VC++中直接使用,如果直接使用的话会出错。
当时我对CSDN正热衷,碰到这种倒霉事情,第一反应就是到CSDN上去问问看,结果到那里问了很长时间也没有人能够解决,一气之下干脆自己研究。最后发现RealPlayer往VC++导出的CLSID是个错误的值,因此导致控件不能使用。找到原因后剩下的事就好办了:我用三种不同的方法从RealPlayer控件往外倒源码,然后把它们凑成一个类,运行的时候用这个类动态创建RealPlayer对象就行了。这段代码就是后来我网站上放出来的RealTest,当时CSDN上有不少人下载过。
可能是RealPlayer控件用得太爽了,当需要对AVI解码的时候我第一个想到的就是Windows Media Player提供的控件,这个控件早就公开了,调用说明也很详细,相比之下比研究AVI解码要容易许多。
因为这些原因,我在Mpeg2Jpeg之后开发了MediaCam,采用控件播放RM、AVI,程序后台对播放画面取快照(即常说的“截屏”技术),软件名称中的Cam(Camera)就是从快照技术来的。因为MPEG4本身还是有损压缩,所以MediaCam中继续使用了Mpeg2Jpeg的图像平均和放大技术。
从使用的结果来看,MediaCam对RM图像的截取还算不错,原因包括:
但是在截取AVI的时候就没有这种好事啦:
在认识到MediaCam的界面是造成截图质量差的最大原因后,我开始开发WMPCam,这个软件采用单纯的对话框界面,上面只有Windows Media Player控件,因此很容易随着画面的大小而改变播放窗口的大小,不会因为对画面进行压缩而影响质量。由于这个软件采用的还是截屏技术,因此软件名称还是使用了Cam后缀。
在用WMPCam截了整部《星界之纹章》后,我开始发觉对于运动比较快的画面,漏截、重复截取实在是一个不能忽视的问题。而要真正解决漏截问题,唯一的办法是回到老路上来--掌握AVI解码技术,逐帧解码AVI画面。因此只好又收拾起精神,彻底抛弃控件,回头考虑怎么对AVI文件解码的问题。
能对AVI文件进行解码的源代码例子不少,我在DOOM9上就找到了VirtualDub、NanDub等的源代码。VirtualDub和NanDub在视频解码方面是一样的,但是文件实在太多,尤其是那一堆ASM文件,实在不是玩的。
就在我犹豫是否下定决心通读NanDub源代码的时候,偶然间在CSDN上看到一篇文章,才突然想起一个一直被我忽略了的问题--AVI其实是标准VFW格式,而对VFW格式微软已经提供足够详细的接口了。至此所有问题迎刃而解:在MSDN上随便搜一下,例子一大把,别说解码AVI,编辑、压缩都够了。
托这些例子的福,我开发出了Avi2Jpeg,在功能上和界面上还参考了NanDub和Mpeg2Jpeg。也就是说,既能连续或跳跃截图,又能用图像平均和高精度放大技术获得高质量的大图片。
因为Avi2Jpeg是直接从AVI媒体流中解码图像帧,没有采用截屏技术,因此不仅不存在漏截的问题,而且运行的时候也不需要设置屏幕显示颜色,或保持播放窗口可见,另外软件也可以不用Cam这个后缀了。从实际使用情况来看,效果比WMPCam要好。
附录:“动画截图工具”系列的选用
| 源文件 | 工具 | 技术 | 说明 |
| VCD | Mpeg2Jpeg | 解码 | |
| AVI(包括标准非压缩AVI、DivX、XDiv) | Avi2Jpeg | 解码 | 使用前请先安装相应解码器,保证Windows Media Player能够正常播放 |
| RM | MediaCam | 截屏 | 使用前请先安装RealPlayer。如果万一WMP图像截取失败,即截出来的图片一片黑,可以在Windows的“开始”菜单中点“运行”,运行程序dxdiag.exe后,在“显示”页中点“禁用”DirectShow硬件加速。截完后再启动硬件加速即可。 |
| ASF等其它MPEG4文件 | WMPCam | 截屏 | 使用前请先安装相应插件,保证Windows Media Player能够正常播放。如果万一图像截取失败,即截出来的图片一片黑,可以在Windows的“开始”菜单中点“运行”,运行程序dxdiag.exe后,在“显示”页中点“禁用”DirectShow硬件加速。截完后再启动硬件加速即可。 |
源文件如果是DVD的话,过程有点麻烦:
这个时候就可以用Avi2Jpeg了。如果你做过DVDrip,上面的过程当然一看就懂。如果看不懂……你还是先去找一份图文并茂的《DVDrip制作攻略》之类的文章看看吧。
不过我不推荐用Avi2Jpeg截DVD,理由如下:
其实对于高手来说,在压缩DVDrip的时候,由于采用某些技术手段,压缩出来的画面质量会比原DVD还好,所以我觉得最好还是压成DVDrip后再截。