您的位置:首页 > 编程语言 > C语言/C++

C++ Builder中制作图片边缘模糊效果的几种方法

2016-11-16 17:46 417 查看
问题描述:

        由于种种需求,需要完成如下图的图像边缘效果。

        


话不多说,完成这种效果我们有以下几种方法:

Way 1:

           FMX有几十种Effect,其中有一种TBlurEffect可以直接实现这种边缘模糊的效果。

           使用起来如:bitmap->addObject(TBlurEffect x),或者添加到图片外的Layout里,还可以在Design界面直接拖进控件中,它就可以帮你模糊掉你所处的Layout,反正使用是非常方便的。如果说你需要让图片模糊效果一直存在,并且不需要存放模糊后的Bitmap的话,这种方法是首选(当然你得把图片贴到上面去,才有这种效果,不然整个都模糊了)。

           为什么要加这么多前提呢?因为,这个控件它并不会主动释放内存!比如说我要做个鼠标移动上去显示模糊,离开图片后,模糊消失的效果,那么就需要使用Visible,Enable,Free,delete,dispose这些方法让Blur失效。然而FMX,并不会帮我们释放掉这个内存,所以切换次数增加后,内存越来越大,图片越大,每次消耗GPU的显存就越高,继而会出现Cannot create a texture for DirectD2D / Out of Memory这种一开始看起来根本摸不到头脑的错误。

Way 2:

           既然不能频繁使用Blur,我们就想到要把做过的效果保存成Bitmap,后来用到的时候就当背景贴上去。一试发现加了Blur的Bitmap中什么效果都没有,后来查了不少资料才发现Effect不能将效果保存在Bitmap里,只能直接显示出来。

          在思考了一段时间后,想到Filter可以保存效果,类似这样:TBlurFilter->ValueAsBitmap["input"] = source->bitmap,TBlurFilter->ValueAsBitmap["output"] (可以在EMB的官方例程ShaderFilters中找到相关写法,我就是慢慢看例程才找到的解决方案,毕竟资料那么少)。在我自信满满的写下TBlurFilter之后,突然发现没有这个filter。。这可如何是好,赶紧去看源码,发现原来TBlurEffect是一种Gaussian模糊的变种,所以使用GaussianFilter调整参数后就可以完成一样的效果。中间有个关键是要用DrawBitmap加上图片边缘的透明像素,这样才行。

          用这种方法,明显减少了显存的占用,但是多张图的时候,还是占了几百M的GPU,为了照顾各种系统,这种方法还是不行。或者可以说,使用起来简单的东西,如果效果又很酷炫的话,总是会有些缺点。

Way 3:

          我们仔细想想模糊的原理,在一位前辈(魔术猫)的指导下,发现我们可以自己制作这种边缘模糊的效果,说出来肯定大家觉得很简单,可是我却想了那么久。。

          方法如下:

 是不是很简单。。直接画了几十张不同透明度的图片做背景,这样组合起来就模糊了~显存的占用也相对在减少,但是要注意这样CPU的占用会高些。其实这些GPU和CPU的占用分析,你程序要是不是很庞大,需要很注重细节的话,根本不需要考虑。

          Dephi

ARect  :=TRectF.Create(0,0,Rectangle1.Width, Rectangle1.Height);
srcRect:=TRectF.Create(0,0,
Rectangle2.Fill.Bitmap.Bitmap.Width,
Rectangle2.Fill.Bitmap.Bitmap.Height);

Rectangle1.Fill.Bitmap.Bitmap.Clear($00000000);

ACanvas:= Rectangle1.Fill.Bitmap.Bitmap.Canvas  ;

ACanvas.BeginScene() ;

for i := 0 to Trunc(Rectangle2.Margins.Left) do begin
ACanvas.DrawBitmap(Rectangle2.Fill.Bitmap.Bitmap,
srcRect,
ARect,
0.1*i/(Rectangle2.Margins.Left+5), true);

ARect.Inflate(-1,-1);
end;
ACanvas.EndScene;

Tips:

      查看源码发现,Firemonkey有4个基本的Blur(单图片模糊效果),分别是BoxBlur,GaussianBlur,RadialBlur,DirectionalBlur。其他的Blur都是对这四个Blur的包装,Filters也有一样的情况,所以并不是所有Blur都有Filter与其对应。

      另外,C++ builder中的.hpp库不是完全翻译的FMX,而是整合,使用的时候,需要看源码学习。

如果你有任何问题或者指出更好的方法,请联系我 QQ:787721594
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: