SkMaskFilter (SkBlurMaskFilter的使用)
還是先看下類的繼承關系:
SkNoncopyable
?????? ∟ SkRefCnt
???????????? ∟SkFlattenable
????????????????? ∟SkMaskFilter
??????????????????????? ∟SkBlurMaskFilterImpl
??????????????????????? ∟SkEmbossMaskFilter
??????????????????????? ∟SkTableMaskFilter
?? ? ? ? ? ? ? ? ? ? ? ?∟SkKernel33ProcMaskFilter
SkBlurMaskFilter
SkBlurMask ?
SkEmbossMask
以上為與MaskFilter相關的類,其他SkBlurMaskFilter/SkBlurMask/SkEmbossMask三個類在effect目錄下的文件中定義。
SkBlurMask 只封裝了靜態成員函數Blur
SkEmbossMask 只封裝了靜態成員函數Emboss
從參數看 Blur 和Emboss 是改變SkMask對象的作用。
SkEmbossMaskFilter 的成員函數 filterMask 用到了SkBlurMask::Blur和SkEmbossMask::Emboss
SkBlurMaskFilterImpl?的成員函數 filterMask 用到了SkBlurMask::Blur。
--------------------------------------------------------------- -------------------------------使用--
要使用MaskFilter要通過類 SkBlurMaskFilter
SkBlurMaskFilter是個獨立的類,沒有繼承關系。
class SK_API SkBlurMaskFilter { public:enum BlurStyle { //模糊風格kNormal_BlurStyle, //!< fuzzy inside and outside 模糊內外kSolid_BlurStyle, //!< solid inside, fuzzy outside 內實體,外模糊kOuter_BlurStyle, //!< nothing inside, fuzzy outside 內部空,外模糊kInner_BlurStyle, //!< fuzzy inside, nothing outside 內模糊,外空kBlurStyleCount //style個數};enum BlurFlags {kNone_BlurFlag = 0x00,/**模糊半徑不被transforms影響 */ kIgnoreTransform_BlurFlag = 0x01,/** 使用smother 高質量模糊算法 */kHighQuality_BlurFlag = 0x02,/** 所有模糊標志的 */kAll_BlurFlag = 0x03};static SkMaskFilter* Create(SkScalar radius, BlurStyle style, uint32_t flags = kNone_BlurFlag);static SkMaskFilter* CreateEmboss( const SkScalar direction[3],SkScalar ambient, SkScalar specular,SkScalar blurRadius); private:SkBlurMaskFilter(); // can't be instantiated };SkBlurMaskFilter 定義了 BlurStyle 類型和?BlurFlags 類型
SkBlurMaskFilter的構造函數是私有成員,不能創建SkBlurMaskFilter類型對象。
然后封裝了兩個靜態成員函數Create(...) 和 CreateEmboss(...)。
Create()函數用它的參數 new 了一個 SkBlurMaskFilterImp l對象。
CreateEmboss()用它的參數 new 了一個 SkEmbossMaskFilter 對象。
1.Create(...) 參數
SkScalar radius:要大于0,模糊效果的半徑? 從圖形邊沿開始算(往里、往外)radius經過或者不經過轉換的值如果超過128(float),會被賦值為128(float)。
BlurStyle style:BlurStyle?
Uint32_t flags:?BlurFlags? ,flags包含kHighQuality_BlurFlag標志時,為高質量,否則是低質量。
相互關系:當flags是kIgnoreTransform_BlurFlag的時候,radius不被矩陣轉換影響,否則會按矩陣轉換。
實際效果1:
flags選擇默認的kNone_BlurFlag,根據style的不同從左到右分別是:
kNormal_BlurStyle:圖形邊界內外都有模糊效果
kSolid_BlurStyle:內部是實體(paint指定的顏色),外邊模糊
kOuter_BlurStyle:內部不繪制,外邊模糊效果
kInner_BlurStyel:內部模糊效果,外部不繪制
實際效果2:
flag選擇kIgnoreTransform_BlurFlag的時候,不同style的效果是(順序同上):
模糊半徑忽略了矩陣變換。只有2像素
實際效果3
flag選擇kHighQuality_BlurFlag的時候,情況如下:
與kNone_BlurFlag在拐角處略有區別。(看眼花了…)
實際效果4:
flag選擇kAll_BlurFlag的時候:
相當于:kHighQuality_BlurFlag(高質量)+kIgnoreTransform_BlurFlag(模糊半徑忽略矩陣)
2.CreateEmboss(...) 參數
const SkScalar direction[3] 指定光源方向
這里的光應該都是平行光(與所畫圖形在屏幕上位置無關), Z軸正向是屏幕往外,理解direction為光源位置。direction到(0,0,0)的向量方向就是平行光的光線方向。
如果設置z軸<=0,就相當于沒有光源在屏幕后面,也就是在圖形后面,無法產生光照效果。
SkScalar ambient 環境光強度? 范圍0---1的scalar值,小于0效果同0,大于1效果同1。
SkScalar specular 鏡面反射光? 范圍0---15.99的scalar值,小于0效果同0,大于15.99效果同15.99。
SkScalar blurRadius 模糊半徑,同Create(...)的參數意義。
效果圖:(最后一個箭頭)
上圖代碼:
void BlurMask_path() {SkPaint embossPaint;embossPaint.setAntiAlias(true);embossPaint.setColor(SK_ColorRED);SkScalar dir[3] ={-5,5,5};SkMaskFilter *embossMask = SkBlurMaskFilter::CreateEmboss(dir,0.5,1,2);embossPaint.setMaskFilter(embossMask);embossMask->unref();SkMaskFilter * blurMask[SkBlurMaskFilter::kBlurStyleCount];for (size_t i = 0;i<SK_ARRAY_COUNT(blurMask);i++){//下面依次實驗flags參數//maskFilter[i] = SkBlurMaskFilter::Create(2,SkBlurMaskFilter::BlurStyle(i));//默認flags//maskFilter[i] = SkBlurMaskFilter::Create(2,SkBlurMaskFilter::BlurStyle(i),//SkBlurMaskFilter::kIgnoreTransform_BlurFlag);//忽略矩陣變換,注意只有模板半徑忽略矩陣變換blurMask[i] = SkBlurMaskFilter::Create(2,SkBlurMaskFilter::BlurStyle(i),SkBlurMaskFilter::kHighQuality_BlurFlag);//maskFilter[i] = SkBlurMaskFilter::Create(2,SkBlurMaskFilter::BlurStyle(i),// SkBlurMaskFilter::kAll_BlurFlag);}SkPaint blurPaint[SK_ARRAY_COUNT(blurMask)];for (size_t i = 0;i<SK_ARRAY_COUNT(blurMask);i++){blurPaint[i].setAntiAlias(true);blurPaint[i].setColor(SK_ColorRED);blurPaint[i].setMaskFilter(blurMask[i]);blurMask[i]->unref();}//DrawImage("\\USER\\Skia\\music-n.png",pskCanvas,g_rtImg,&embossPaint); //對畫圖片沒效果float pts[]={0, 0,10, 0,10, 5,20, -5,10, -15,10, -10,0, -10}; //將這些坐標連起來是一個箭頭形狀SkPath fPath;fPath.moveTo(pts[0], pts[1]);for (size_t i = 2; i < SK_ARRAY_COUNT(pts); i += 2) {fPath.lineTo(pts[i], pts[i+1]);}pskCanvas->scale(5,5); //水平垂直都放大5倍pskCanvas->translate(10,30); //移動坐標原點for (size_t i = 0;i<SK_ARRAY_COUNT(blurMask);i++){pskCanvas->drawPath(fPath, blurPaint[i]);pskCanvas->translate(32, 0); //水平移動32像素(實際效果要經過scale)}pskCanvas->drawPath(fPath, embossPaint); }(箭頭數組來源:http://code.google.com/p/skia/source/browse/trunk/samplecode/SampleEffects.cpp)
分析關于光源的方向:
選定光源指定后,效果與所畫圖形在屏幕的位置無關,是平行光。
光源在不同x,y坐標情況下,其他參數同上面代碼:z坐標5,環境光0.5,反射光1,模糊半徑2,效果圖如下:
x軸向左?Y軸向上 ,z軸向屏幕外。
以備補充:
ezhong的博客園:http://www.cnblogs.com/ezhong/? ? ?2011-11-30/17:53:47
轉載于:https://www.cnblogs.com/ezhong/archive/2011/11/30/2269501.html
總結
以上是生活随笔為你收集整理的SkMaskFilter (SkBlurMaskFilter的使用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十一月最后一天
- 下一篇: KlayGE 4.0中Deferred