700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 从零开始实现图片加载特效之黑白照片 倒影图片 图片蒙版

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

时间:2024-04-14 09:42:46

相关推荐

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

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

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

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

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

public class MaskDisplayer implements Displayer {public MaskDisplayer(Masker mMasker) {this.mMasker = mMasker;}Masker mMasker;@Overridepublic 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{@Overridepublic 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 {@Overridepublic 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;}@Overridepublic 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地址 /gengqiquan/HelloLoader.git

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。