从零开始实现图片加载特效之黑白照片、倒影图片、图片蒙版

来源:互联网 发布:ios网易新闻app源码 编辑:程序博客网 时间:2024/06/11 20:48

尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/53168797, 本文出自:【gengqiquan的博客】

之前有写了一个从零开始实现一个网络图片加载框架,实现了基本的加载网络和图片功能

然后上篇博客 从零开始实现图片加载特效之渐变加载、圆角图片分别介绍渐变加载和圆角图片了两种加载特效的实现方式,今天我们来一起实现其他三种蒙版特效,分别为倒影特效,灰度照片,遮罩特效

之前我们把图片的最终加载交由了图片加载器displayer,这里我们再写一个displayer,提供蒙版处理的代理

public class MaskDisplayer implements Displayer {    public MaskDisplayer(Masker mMasker) {        this.mMasker = mMasker;    }    Masker mMasker;    @Override    public void display(Bitmap bm, ImageInfo info) {        ImageView imageView = info.getImageView();        bm = mMasker.mask(bm);        if (bm != null && !bm.isRecycled()) {            imageView.setImageBitmap(bm);        }    }}

蒙版的抽象为

public interface Masker {    Bitmap mask(Bitmap bm);}

我们将这个抽象实现为具体的灰度处理masker

public class GrayMasker implements Masker{    @Override    public Bitmap mask(Bitmap bm) {        Bitmap mGrayBitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);        Canvas mCanvas = new Canvas(mGrayBitmap);        Paint mPaint = new Paint();        //创建颜色变换矩阵        ColorMatrix mColorMatrix = new ColorMatrix();        //设置灰度影响范围        mColorMatrix.setSaturation(0);        //创建颜色过滤矩阵        ColorMatrixColorFilter mColorFilter = new ColorMatrixColorFilter(mColorMatrix);        //设置画笔的颜色过滤矩阵        mPaint.setColorFilter(mColorFilter);        //使用处理后的画笔绘制图像        mCanvas.drawBitmap(bm, 0, 0, mPaint);        return mGrayBitmap;    }}

我习惯给代码加注释,所以就不一句句的去讲解什么意思了,相信大家可以通过注释看懂。

然后去在加载图片的时候调用

    LoaderConfigure configure = new LoaderConfigure()       .displayer(new MaskDisplayer(new GrayMasker()));        HelloLoader.bind(mImageView).LoaderConfigure(configure).load(mImageUrl);

来构建一个灰度照片蒙版加载器

我们看下效果

这里写图片描述

可以看到类似于黑白照片的效果,但又不像黑白照片那样泾渭分明,熟悉Photoshop的就该知道,这是里面的去色效果,这里就叫做灰度照片吧

接下来我们实现倒影效果,这里我们还是通过masker

写一个倒影的masker

public class ReflectedMasker implements Masker {    @Override    public Bitmap mask(Bitmap bm) {        int width = bm.getWidth();        int height = bm.getHeight();        Matrix mMatrix= new Matrix();       // 图片缩放,x轴变为原来的1倍,y轴为-1倍,实现图片的反转       mMatrix.preScale(1, -1);        //创建反转后的图片Bitmap对象,图片高是原图的一半。        Bitmap mInverseBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, mMatrix, false);        Bitmap mReflectedBitmap = Bitmap.createBitmap(width, height * 2, Bitmap.Config.ARGB_8888);        // 把新建的位图作为画板,绘制图片        mCanvas.drawBitmap(bm, 0, 0, null);        mCanvas.drawBitmap(mInverseBitmap, 0, height, null);        //添加倒影的渐变效果        Paint mPaint = new Paint();        Shader mShader = new LinearGradient(0, height, 0, mReflectedBitmap.getHeight(), 0x70ffffff, 0x00ffffff, Shader.TileMode.MIRROR);        mPaint.setShader(mShader);        //设置叠加模式        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));        //绘制蒙版遮罩效果        mCanvas.drawRect(0, height, width, mReflectedBitmap.getHeight(), mPaint);        return mReflectedBitmap;    }}

给倒影的图片做了渐变遮罩蒙版效果,看起来更像水中倒影,如果要更像可以做一些扭曲处理,这里就不写了,感兴趣的可以自己去研究,还是比较好玩的。
然后我们一样在加载图片的时候调用

  LoaderConfigure configure = new LoaderConfigure()       .displayer(new MaskDisplayer(new ReflectedMasker()));        HelloLoader.bind(mImageView).LoaderConfigure(configure).load(mImageUrl);

再来看下效果

这里写图片描述

写到这里,熟悉Photoshop的童鞋可能发现了,这些效果不都是Photoshop里才可以实现的么?答案是肯定的,因为Photoshop也是一个代码写就的软件,我们当然也可以通过代码实现相同的功能,只不过有些功能实在太耗费性能,在手机端很不提倡罢了。

最后放个大招,图片蒙版混合模式,了解的童鞋应该知道这个功能有多强大。混合模式有很多种,这里我们来展示其中一种,说是展示是因为我们将把模式指定抽取出来,这样大家可以根据自己实际需求去指定适合的模式

写一个图片蒙版混合模式master,这里的蒙版图片我选择用资源id的方式传入,大家可以根据自己需求更改

public class PorterDuffMasker implements Masker {    int shadeID;    Resources res;    PorterDuff.Mode mode;    public PorterDuffMasker(Resources res, int shadeID, PorterDuff.Mode mode) {        this.shadeID = shadeID;        this.res = res;        this.mode = mode;    }    @Override    public Bitmap mask(Bitmap bm) {        //如果不用copy的方法,直接引用会对资源文件进行修改,而Android是不允许在代码里修改res文件里的图片        Bitmap mShadeBitmap = BitmapFactory.decodeResource(res, shadeID);        //缩放至于底部图片一样大小        mShadeBitmap = ImageUtil.scaleImg(mShadeBitmap,bm.getWidth(), bm.getHeight());        //画板图片不建议直接在原图上做更改        bm = bm.copy(Bitmap.Config.ARGB_8888, true);        Canvas mCanvas = new Canvas(bm);        Paint mPaint = new Paint();        //设置混合模式        mPaint.setXfermode(new PorterDuffXfermode(mode));        mCanvas.drawBitmap(mShadeBitmap, 0, 0, mPaint);        return bm;    }}

在加载图片时将机器人图片传进去作为图片蒙版

这里写图片描述

记得不规则的图片作为图片蒙版要是PNG格式的喔

选择PorterDuff.Mode.DST_IN,取上层图片形状,显示下层图片

   LoaderConfigure configure = new LoaderConfigure()       .displayer(new MaskDisplayer(new PorterDuffMasker(getResources(),R.mipmap.ic_launcher,PorterDuff.Mode.DST_IN)));        HelloLoader.bind(mImageView).LoaderConfigure(configure).load(mImageUrl);

看下效果
这里写图片描述

怎么样?有意思吧。大家还可以切换不同的混合模式看看效果

完整的示例项目Githu地址 https://github.com/gengqiquan/HelloLoader.git

有什么意见和疑惑欢迎留言

我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。

1 0
原创粉丝点击