您好,欢迎访问一九零五行业门户网

利用自定义View实现头像截取页面_html/css_WEB-ITnose

在一些应用中,特别是有帐号体系的应用,通过相册选择图片和照相机拍照,然后对所获取的头像进行截取,最后获取选择框中的内容作为头像,一般效果会如下显示:
那么,如何制作这样一个效果呢,关键点在哪里呢?
做法其实可以有多种,
1)可以直接继承imageview,然后在imageview的ondraw函数中直接绘制圆形或者方形的高亮圈;
2)也可以直接继承view,自己将bitmap给传进来,在ondraw函数中先绘制图片,接着利用path来绘制这个圆形或者方形的选择区域,利用region.op.difference来反向获取蒙板层。
不过利用clippath来实现这个蒙板层的绘制,画出来的圆形会有锯齿,这个目前我还没有找到比较好的办法去掉这个锯齿,不知道有没有哪位朋友能够提供一下建议。
关键代码如下:
@override protected void ondraw(canvas canvas) { if(!misinit){ initcroprect(getwidth(), getheight()); moptbitmap = getproperbitmap(mbitmap, mcroprect.width()); ... misinit = true; } canvas.save(); canvas.concat(mdrawmatrix); canvas.drawbitmap(moptbitmap, 0, 0, null); canvas.restore(); if(mtodrawhighlight){ canvas.save(); mpath.reset(); if (miscircle) { float radius = mcroprect.width() / 2 ; mpath.addcircle(mcroprect.left + radius, mcroprect.top + radius, radius, path.direction.cw); } else { mpath.addrect(mcroprect, path.direction.cw); } canvas.clippath(mpath, region.op.difference); canvas.drawpaint(mdimpaint); canvas.restore(); } }
大家只关注关键代码即可。
首先,在第一次ondraw的时候,已经可以获取当前view和bitmap的大小,这个时候,我们要先确定croprect,也即选择框的大小和范围,不管是圆形,还是方形,其实都是一个正方形区域,所以,首先要确定这个区域,这是在代码initcroprect中实现的。
而紧接着的操作,其实是对图片的一些移动和缩放操作,为了使图片能够居中,或者将比较小的图片放大到选择区域那么大,大家可先暂时忽略。
接下来利用canvas.drawbitmap将对应的位图画出来先。
第二步,我们要先定义一个path,根据画圆还是画方,在path上添加一个图形,然后利用clippath和region.op.difference来反向获取蒙板区域,然后在canvas上利用mdimpaint来画蒙板(mdimpaint就是一个颜色为半透明的画笔,这样才不会遮盖掉画在下面的bitmap)。
画出蒙板和选择圈之后,更多时候,我们还需要对图片进行移动和缩放,类似于微信和支付宝那样,那么我们可以利用gesturedetector和scalegesturedetector来实现对移动和缩放的控制,如下:
mscalegesturedetector = new scalegesturedetector(context, this);mgesturedetector = new gesturedetector(context, new mygesturelistener());
其中mygesturelistener是我们自定义的一个gesturedetector,因为我们并不需要太多的gesture,所以我们可以利用simpleongesturelistener来实现我们处理,如下:
class mygesturelistener extends simpleongesturelistener { @override public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey){ mdrawmatrix.posttranslate(-distancex, -distancey); checkborderwhentranslate(); return true; } }
其实很简单,在当前view上往某个方向移动的时候,我们是需要将canvas反方向移动,这样画出来的bitmap才是跟着我们手指移动,所以这里为什么是负数的distance的原因就在这。
这只是针对移动的,还需要缩放的,我们就需要实现一个onscalegesturelistener,让当前的view去实现此接口即可,如下:
float scalefactor = detector.getscalefactor(); float[] values = new float[9]; mdrawmatrix.getvalues(values); float curscale = values[matrix.mscale_x]; if ((curscale 1.0f) || (curscale > minitscale && scalefactor scale_max) { scalefactor = scale_max / curscale; } mdrawmatrix.postscale(scalefactor, scalefactor, detector.getfocusx(), detector.getfocusy()); checkborderandcenterwhenscale(); } return true;
这里边具体的逻辑就依赖于各位朋友自己的想法了,最后不要忘了,从哪里获取到这些移动事件呢,当然是ontouch方法里面,如下:
@override public boolean ontouch(view v, motionevent event) { ... mscalegesturedetector.ontouchevent(event); mgesturedetector.ontouchevent(event); invalidate(); return true; }
好了,关于如何利用自定义view截取头像的大概思路就跟各位朋友说到这了,大家可以自行根据此思路再完善一下。
其它类似信息

推荐信息