在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作。可能是我的设置问题,也可能是SharpDx对VB2010支持的不够好(用C#就没有问题) ,有网友将代码贴到VB2012中,也发现可以运行的很好。由于手头上没有VS2012,故这个功能的实验放置一段时间
不过,回过头想一想。我们需要WIC的图片编码功能么?
Direct2D(SharpDx等)的显示绘制优势
和GDI、GDI+相比,Direct2D(SharpDx等)的优势在于利用硬件(GPU)绘制,节省时间,节省CPU的占用率,提高绘制效率。
GDI、GDI+等的绘制流程如下:
1、GDI、GDI+将绘制命令传到CPU
2、CPU开始在内存中绘制图形
3、CPU将绘制完的图形传到GPU
4、GPU将图形传到显示设备(显示器等)
Direct2D(SharpDx等)的绘制模式有Hardware(基于硬件)、Software(基于软件)、Default(默认)
其中Software模式和GDI、GDI+绘制流程一样。Default模式在初始化的时候会进行硬件检测,如果硬件支持,则采用Hardware模式,如果硬件不支持,则采用Software模式
Direct2D(SharpDx等)在模式选择为Hardware时的绘制流程如下:
1、Direct2D(SharpDx等)将绘制命令传到CPU
2、CPU将绘制命令传到GPU
3、GPU在显存中绘制图形
4、GPU将绘制好的图形传到显示设备(显示器等)
上述两个流程的区别在于:
GDI、GDI+等是利用CPU绘制图形,绘制图形在内存中有备份。
Direct2D(SharpDx等)的Hardware模式是利用GPU绘制图形,内存中并没有备份。和GDI、GDI+等相比优势在于快,节省CPU占用(GPU的绘制效率远高于CPU)。但也有一些问题,就是CPU将绘制命令传到GPU后,就不管了,至于GPU绘制成什么样子,那就是GPU的事了。这也可以解释为何早期的显卡,有时会出现渲染的错误。
WIC如何将绘制的图形编码到图形文件
在Direct2D的说明帮助里提到,如果需要利用WIC将RenderTarget上的内容编码到图形文件中的话,则得把RenderTarget的模式设置为Software(不能是Hardware,以目前的电脑配置Default基本上等同于Hardware)
WIC将RenderTarget上的内容编码到图形文件的流程如下:
1、创建WicBitmap对象,再之上创建WicRenderTarget对象
2、创建D2DBitmap对象,再利用CopyFromRenderTarget方法把RenderTarget上的内容复制到D2DBitmap对象
3、利用WicRenderTarget对象的DrawBitmap方法把D2DBitmap对象绘制到WicBitmap对象上
4、创建BitmapEncoder对象,在之上创建BitmapFrameEncoder对象,并创建和BitmapEncoder相关的Stream对象
5、将WicBitmap对象写入到BitmapFrameEncoder对象
6,调用BitmapFrameEncoder对象和BitmapEncoder对象的Commit方法,将内容编码到Stream对象,可以保存到文件
在Software模式下,是利用CPU绘制图形,结果在内存中有缓存。WIC的WicRenderTarget对象的DrawBitmap方法能把缓存中的内容绘制到WicBitmap上。
而在Hardware模式下,利用的是GPU绘制图形,在内存中没有缓存。WIC的WicRenderTarget对象的DrawBitmap方法没法把内容绘制到WicBitmap上(因为缓存中没有),强行调用的话,会报错的。
我们需要WIC的图片编码功能么?
用Direct2D(SharpDx等)就是看重其硬件加速的能力,但也籍此不能使用WIC保存绘制的内容;如果要使用WIC保存绘制的内容,则Direct2D(SharpDx等)的绘制模式设置为Software,但又牺牲了硬件加速能力,其效率和GDI、GDI+等相差无几。
再加上WIC实际上是调用系统默认的编码器对图形进行编码,但同时几乎不提供的可调参数的功能。例如:我们知道在保存JPG的时候,可以设置精度(因为JPG是有损压缩,根据精度的不同,保存的文件大小也不相同),但是用WIC保存为JPG的时候,却没有参数可以设置精度(或者是我没找到);保存为GIF时,可以设置每帧之间的间隔时间,但在WIC中也没有相应的属性可以提供(也许可以通过添加MetaData的方式设置该属性)。
换个角度考虑,图形的编码远比解码复杂的多。解码图形,只要依据已经存在的数据按照一定的规则解码就行了,即使是用不同的解码器解码出来的图形应该是毫无二致。但是,编码就不同了,同样的格式、同样的参数,不同的编码器出来的文件可能就不一样了(我们用PS和Fireworks编码出来的GIF文件大小就不一样)。
因此,如果是采用默认编码器对图形编码的话,真不一定需要WIC(WIC仅仅是提供了一个调用的途径),在GDI+中完全可以利用Bitmap对象的Save方法做到。如果需要对编码进行参数设置的话,以获得不同的文件的话,这个似乎WIC又做不到。
因此,看来我们并不需要WIC的图片编码功能。再说,我们使用Direct2D(SharpDx等)是依靠其硬件加速的能力,加强图形渲染功能。
现在在研究GIF的编码,发现 Robin 写的系列文章不错。待研究后再书新文
本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/p/3356750.html,如需转载请自行联系原作者