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

Posted gengqiquan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始实现图片加载特效之黑白照片倒影图片图片蒙版相关的知识,希望对你有一定的参考价值。

尊重他人的劳动成果,转载请标明出处: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技术问题,有兴趣的可以加下,大家一起进步。

以上是关于从零开始实现图片加载特效之黑白照片倒影图片图片蒙版的主要内容,如果未能解决你的问题,请参考以下文章

图片的水波倒影效果

想在网页中插入一个图片水波倒影的效果应该怎么实现?看教程是需要一个lake.class的文件

HTML5图片水面倒影和波纹动画,超逼真

[js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)

给商品设置倒影

html5 canvas系列教程-像素操作(反色,黑白,亮度,复古,蒙版,透明)