还是先看下类的继承关系:

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