安卓画笔setShadowLayer与SetMaskFilter绘制图片无效

2,603 阅读2分钟

安卓自定义 View 踩坑笔记,特作文记录

安卓 Paint 类用于自定义 View 时↑这两个方法能用来干嘛我就不细说了,大家应该都了解,总结而言我们可以用这两个方法给要绘制的东西添加阴影和发光效果。发光效果我们这里只讨论内外发光。

这俩方法在大多数场景下要生效都需关闭硬件加速,这点大家肯定都知道。有时我们需要把阴影或发光效果应用在绘制图片(Bitmap)时,此时 UI 给你切的小图标很可能是边缘会有一大圈纯透明像素,此时你会发现给 Paint 设置了上面两个函数后得不到想要的效果。

问题其实就出在切图边缘有纯透明像素上。

我们直接上图来看看效果。

比如吧我现在有张图长这样:

原图

这是我从 AS 里打开图片后截的预览效果图,注意它边缘那一大圈透明像素。我们绘制此图片时想给它加个阴影效果:

mArcPaint.setShadowLayer(20, dp2px(15), dp2px(15), Color.parseColor("#333333"));//dp2px干嘛的大家肯定能猜到
canvas.drawBitmap(mArrow, matrix, mArcPaint);//mArrow 就是我们待绘制的 Bitmap 对象
mArcPaint.clearShadowLayer();

绘制到画布上是这么个尴尬样子:

原图1绘制阴影1

我们把模糊半径设置成 0 :

mArcPaint.setShadowLayer(0, dp2px(15), dp2px(15), Color.parseColor("#333333"));//dp2px干嘛的大家肯定能猜到
canvas.drawBitmap(mArrow, matrix, mArcPaint);//mArrow 就是我们待绘制的 Bitmap 对象
mArcPaint.clearShadowLayer();

会变成这样:

原图1绘制阴影2

看着只有原图了!

此时我们把原图改成这样:

原图2

嗯周围没有纯透明像素了,此时再把模糊半径改大点:

mArcPaint.setShadowLayer(128, dp2px(15), dp2px(15), Color.parseColor("#333333"));//dp2px干嘛的大家肯定能猜到
canvas.drawBitmap(mArrow, matrix, mArcPaint);//mArrow 就是我们待绘制的 Bitmap 对象
mArcPaint.clearShadowLayer();

此时绘制到画布上是这样的:

原图2绘制阴影

相信我上面已经说的很明白了!

发光效果没画出来也是如此。

发光效果的设置代码大概长这样:

mArcPaint.setMaskFilter(new BlurMaskFilter(dp2px(4), BlurMaskFilter.Blur.NORMAL));//生产环境里千万不要在onDraw 函数里 new 对象!会 OOM 的
canvas.drawBitmap(mArrow, matrix, mArcPaint);
mArcPaint.setMaskFilter(null);

原图:

原图

内外发光效果绘制到画布上:

原图绘制内外发光

完。