本发明涉及静态图的标识点生成及静态图的缩放处理技术领域,具体说是一种图片缩放的方法。所述图片即指静态图。
背景技术:
现有的静态图,在展示给用户后,因为某些需求,要在图中指定位置增加标识点,例如:在人体构造图片中,指定位置增加标识点以便标识各个穴位,再例如:在合影照片中,指定位置增加标识点以便标识人像信息,又例如:在酷我音乐盒中,当用户进行上传头像或制作音乐片段时,用户可选择本地图片并上传到服务器,上传的图片将作为头像或音乐播放展示图片,此时,支持用户对图片进行拉伸和缩放,还支持进行个性化修图,此时,如果用户给图片某个位置做个标记或者水印之后,再次操作图片进行拉伸和缩放时,则存在标识点错位问题,需要进行优化、改进。
现有技术中,当在一张图片(静态图片)上标识一个标识点(坐标点)时,如果后期对图片进行缩放和移动时,往往这个标识点不能跟随图片的变化而自动调整位置,导致标识点错位,新生成的标识点,其相对位置不能准确的对应于原始的标识点。
技术实现要素:
针对现有技术中存在的缺陷,本发明的目的在于提供一种图片缩放的方法,支持静态图的标识点生成,支持图片进行缩放和移动,且缩放和移动后,能对原始的标识点自动调整位置,保持标识点相对位置不变,标识准确,适合图片标识需求的用户使用,提升用户体验。
为达到以上目的,本发明采取的技术方案是:
一种图片缩放的方法,其特征在于,包括如下步骤:
设定用于生成标识容器的边框控件tagcontainer及用于图片缩放和移动的图片控件easytouchview,其中:
边框控件tagcontainer,集成android系统提供的framelayout控件,
图片控件easytouchview,集成android系统提供的imageview控件,
在边框控件tagcontainer中:
定义资源文件r.drawable.bg_tag,用于呈现一图像作为用户可辨识的标识点,
通过textview.setbackgroundresource(r.drawable.bg_tag)加载该资源文件,
通过framelayout提供的apiaddview(textview)往帧布局中添加控件;
在图片控件easytouchview中:
定义pointf的对象startpoint和midpoint,记录点击的开始点和中心点,pointf是android系统提供的表示一个坐标点的工具类,
定义缩放矩阵matrix的对象matrix和currentmaritx,
定义bitmap对象bitmap,
设置bitmap的scaletype属性为矩阵类型scaletype.matrix,
第一次进入页面需要将图片放到中心位置,对其进行缩放处理,
在ontouchevent事件处理中,处理按下、滑动和抬起状态的情况;
边框控件tagcontainer及图片控件easytouchview联动,具体包括:
通过xml布局,在java类中获取tagcontainer标签容器对象,设置layoutparams布局参数,设定好标签的坐标以及距离标签容器的上下左右四个方向的边距,调用标签容器的createtextview在设定好的位置显示标签,
当拖动图片的时候,调用监听器的move接口,将移动的距离实时传递给标签容器控件tagcontainer,通过move接口,获取移动的横坐标dx和纵坐标dy,重新设置标签控件距离父布局tagcontainer的上下左右四个边距,
当缩放图片的时候,通过newscale接口,将缩放数值传递给标签控件,重新计算标签控件距离父布局控件tagcontainer的上下左右边距。
在上述技术方案的基础上,在边框控件tagcontainer中,定义生成控件方法createtag,
方法createtag设定一输入参数params,params是布局参数layoutparams的变量,包含了控件的宽高属性,
定义上下文变量context对象mcontext,是android系统生成新控件需要的参数,
执行newtextview(mcontext)并赋值给文本控件textview的对象textview,
执行textview.setlayoutparams(params)设定参数,
执行textview.setbackgroundresource(r.drawable.bg_tag)设定资源文件,
最后在该方法中通过framelayout提供的apiaddview(textview)往帧布局中添加控件。
在上述技术方案的基础上,在图片控件easytouchview中,通过imageview中获取图像的apigetdrawable将xml中配置的资源图片转换成bitmapdrawable对象,
再调用bitmapdrawable对象的getbitmap函数,实现获取bitmap对象。
在上述技术方案的基础上,第一次进入页面时,进行如下缩放处理,
通过easytouchview控件的apigetcontext获取上下文,存入context,
通过上下文获取资源配置对象,进而获取手机屏幕信息displaymetrics对象,具体包括屏幕的宽高信息,
用屏幕的宽度除以图片的宽度获取宽度的缩放比例,用屏幕的高度除以图片的高度,获取高度的缩放比例,
使用缩放矩阵的postscale函数,设置图片的缩放比例值,
调用setimagematrix给easytouchview控件重新设置缩放比例,实现按照图片的宽高来进行自动缩放。
在上述技术方案的基础上,当拖动图片的时候,获取移动的横坐标dx和纵坐标dy后,执行以下算法:
intnewleft=(int)(left+dx);
intnewright=(int)(top+dy);
left是在按下的时候,获取标签控件的距离父布局控件tagcontainer的左边距,
top是按下的时候获取标签控件的距离父布局控件tagcontainer的上边距,
newleft和newright就是拖动后,相对原来位置移动后的新的距离父布局控件tagcontainer的间距,
调用layoutparams的apisetmargins重新设置左边距和上边距,再重新设置给标签控件,即在新的位置显示图片。
在上述技术方案的基础上,当缩放图片的时候,重新计算标签控件距离父布局控件tagcontainer的上下左右边距的算法为:
floatnewleft=left*tscale;
floatnewtop=top*tscale;
调用按下时的左边距和右边距乘以缩放倍数,计算出新的左右边距,再重新设置给标签控件,以达到缩放时标签跟随图片相对位置不变的效果。
本发明所述的图片缩放的方法,支持静态图的标识点生成,支持图片进行缩放和移动,且缩放和移动后,能对原始的标识点自动调整位置,保持标识点相对位置不变,标识准确,适合图片标识需求的用户使用,提升用户体验。
本发明所述的图片缩放的方法,在酷我音乐盒中,当用户进行上传头像或制作音乐片段时,用户可选择本地图片并上传到服务器,上传的图片将作为头像或音乐播放展示图片,此时,支持用户对图片进行拉伸和缩放,还支持进行个性化修图,此时,如果用户给图片某个位置做个标记或者水印之后,再次操作图片进行拉伸和缩放时,如果采用本发明的技术方案,则不会出现标识点错位问题,标记和水印会显示在图片的相对位置,不会变化,在做图片个性化时更便于用户使用。
附图说明
本发明有如下附图:
图1本发明的流程图。
具体实施方式
以下结合附图对本发明作进一步详细说明。
如图1所示,本发明所述的图片缩放的方法,包括如下步骤:
设定用于生成标识容器的边框控件tagcontainer及用于图片缩放和移动的图片控件easytouchview,其中:
边框控件tagcontainer,集成android系统提供的framelayout控件,
图片控件easytouchview,集成android系统提供的imageview控件,
在边框控件tagcontainer中:
定义资源文件r.drawable.bg_tag,用于呈现一图像作为用户可辨识的标识点,
通过textview.setbackgroundresource(r.drawable.bg_tag)加载该资源文件,
通过framelayout提供的apiaddview(textview)往帧布局中添加控件;
在图片控件easytouchview中:
定义pointf的对象startpoint和midpoint,记录点击的开始点和中心点,pointf是android系统提供的表示一个坐标点的工具类,
定义缩放矩阵matrix的对象matrix和currentmaritx,matrix是一个3*3的矩阵工具类,对图片或view组件的处理分为以下4种:
translate————平移变换,
scale————缩放变换,
rotate————旋转变换,
skew————错切变换,
定义bitmap对象bitmap,bitmap是android系统提供的表示一张图片的信息,用它可以获取图像文件信息,进行图像颜色变换、剪切、旋转、缩放等操作,并可以指定格式保存图像文件,根据xml布局文件来获取bitmap对象,
设置bitmap的scaletype属性为矩阵类型scaletype.matrix,scaletype属性决定了图片在view上显示时的样子,如进行何种比例的缩放,及显示图片的整体还是部分等等,这里设置为矩阵类型,以便实现图片的缩放和移动,
第一次进入页面需要将图片放到中心位置,对其进行缩放处理,
在ontouchevent事件处理中,处理按下、滑动和抬起状态的情况;
边框控件tagcontainer及图片控件easytouchview联动,具体包括:
通过xml布局,在java类中获取tagcontainer标签容器对象,设置layoutparams布局参数,设定好标签的坐标以及距离标签容器的上下左右四个方向的边距,调用标签容器的createtextview在设定好的位置显示标签,
当拖动图片的时候,调用监听器的move接口,将移动的距离实时传递给标签容器控件tagcontainer,通过move接口,获取移动的横坐标dx和纵坐标dy,重新设置标签控件距离父布局tagcontainer的上下左右四个边距,
当缩放图片的时候,通过newscale接口,将缩放数值传递给标签控件,重新计算标签控件距离父布局控件tagcontainer的上下左右边距。
在上述技术方案的基础上,在边框控件tagcontainer中,定义生成控件方法createtag,
方法createtag设定一输入参数params,params是布局参数layoutparams的变量,包含了控件的宽高属性,
定义上下文变量context对象mcontext,是android系统生成新控件需要的参数,
执行newtextview(mcontext)并赋值给文本控件textview的对象textview,
执行textview.setlayoutparams(params)设定参数,
执行textview.setbackgroundresource(r.drawable.bg_tag)设定资源文件,
最后在该方法中通过framelayout提供的apiaddview(textview)往帧布局中添加控件。
在上述技术方案的基础上,在xml布局中,通过layout_match和layout_wrapcontent调整输入参数params。
在上述技术方案的基础上,调用layoutparams的apisetmargins,设置距离父布局的上下左右边距,并传给输入参数params。
在上述技术方案的基础上,在图片控件easytouchview中,通过imageview中获取图像的apigetdrawable将xml中配置的资源图片转换成bitmapdrawable对象,
再调用bitmapdrawable对象的getbitmap函数,实现获取bitmap对象。
例如:可采用如下代码:
bitmapdrawablebd=(bitmapdrawable)getdrawable();
bitmap=bd.getbitmap()。
在上述技术方案的基础上,第一次进入页面时,进行如下缩放处理,
通过easytouchview控件的apigetcontext获取上下文,存入context,
通过上下文获取资源配置对象,进而获取手机屏幕信息displaymetrics对象,具体包括屏幕的宽高信息,
用屏幕的宽度除以图片的宽度获取宽度的缩放比例,用屏幕的高度除以图片的高度,获取高度的缩放比例,
使用缩放矩阵的postscale函数,设置图片的缩放比例值,
调用setimagematrix给easytouchview控件重新设置缩放比例,实现按照图片的宽高来进行自动缩放。
例如,可采用如下代码:
protectedvoidcenter(){
contextcontext=getcontext();
displaymetrics=context.getresources().getdisplaymetrics();
floatscalex=displaymetrics.widthpixels*1.0f/bitmap.getwidth();
floatscaley=displaymetrics.heightpixels*1.0f/bitmap.getheight();
matrix.postscale(scalex,scaley);
setimagematrix(matrix);
}。
在上述技术方案的基础上,当拖动图片的时候,获取移动的横坐标dx和纵坐标dy后,执行以下算法:
intnewleft=(int)(left+dx);
intnewright=(int)(top+dy);
left是在按下的时候,获取标签控件的距离父布局控件tagcontainer的左边距,
top是按下的时候获取标签控件的距离父布局控件tagcontainer的上边距,
newleft和newright就是拖动后,相对原来位置移动后的新的距离父布局控件tagcontainer的间距,
调用layoutparams的apisetmargins重新设置左边距和上边距,再重新设置给标签控件,即在新的位置显示图片。
例如,可采用如下代码:
textviewchild=(textview)mcontainer.getchildat(0);
layoutparamsparams=child.getlayoutparams();
intnewleft=(int)(left+dx);
intnewright=(int)(top+dy);
params.setmargins(newleft,newright,0,0);
child.setlayoutparams(params);
mcontainer是标签容器tagcontainer的对象,调用getchildat(0)就获取了之前生成的标签控件,再获取标签控件的布局参数对象params,计算新的距离父布局控件tagcontainer的上下左右四个边距。
在上述技术方案的基础上,当缩放图片的时候,重新计算标签控件距离父布局控件tagcontainer的上下左右边距的算法为:
floatnewleft=left*tscale;
floatnewtop=top*tscale;
调用按下时的左边距和右边距乘以缩放倍数,计算出新的左右边距,再重新设置给标签控件,以达到缩放时标签跟随图片相对位置不变的效果。
以下为处理滑动和缩放的代码示例:
publicbooleanontouchevent(motioneventevent){
switch(event.getaction()){
casemotionevent.action_down:
mode=drag;
currentmaritx.set(getimagematrix());startpoint.set(event.getx(),event.gety());
break;
casemotionevent.action_pointer_down:
mode=zoom;
startdis=distance(event);
midpoint=newpointf(0,0);
currentmaritx.set(this.getimagematrix());
break;
casemotionevent.action_move:
if(mode==drag){
floatdx=event.getx()-startpoint.x;
floatdy=event.gety()-startpoint.y;
if(mlistener!=null){
mlistener.move(dx,dy);
}
matrix.set(currentmaritx);
matrix.posttranslate(dx,dy);
}elseif(mode==zoom){
floatenddis=distance(event);
floatscale=enddis/startdis;
matrix.set(currentmaritx);
matrix.postscale(scale,scale,midpoint.x,midpoint.y);
if(mlistener!=null){
mlistener.newscale(scale);
}
}
setimagematrix(matrix);
break;
casemotionevent.action_pointer_up:
mode=0;
break;
casemotionevent.action_up:
mode=0;
break;
}
其中:
event.getaction()可以获取点击的动作,比如按下状态和一个手指按下另一个手指再按下的状态,还有滑动状态和抬起手指的状态等,mode记录了实时的拖拽状态还是放大缩小状态的变量,event.getx()和event.gety()表示点击的x坐标和y坐标;定义整形变量drag为1,表示拖动状态,定义整形变量zoom为2,表示放大状态;mlistener是向外界传递数据的监听器,在生成控件的时候就需要设置该监听器,包括了移动move和缩放倍数newscale两个接口,实时的将数据传递给tagcontainer控件。
(1)单个手指按下状态motionevent.action_down
将mode设置为drag拖动状态,步骤2.2的currentmaritx设置当前图像矩阵,getimagematrix()是imageview提供的api,可以获取当前图像矩阵,包括图像位置和缩放信息,设置步骤1.1开始点startpoint的坐标为当前手指按下的x和y坐标;
(2)另一个手指按下的状态,motionevent.action_pointer_down
将mode设置为zoom缩放状态,获取两个手指所点击的间距startdis,方法是distance,
privatestaticfloatdistance(motioneventevent){
floatdx=event.getx(1)-event.getx(0);
floatdy=event.gety(1)-event.gety(0);
returnfloatmath.sqrt(dx*dx+dy*dy);
}
其中,event就是点击事件,调用其中的getx(1)和getx(0),就获取了点击的横坐标的两个点,通过直角三角形函数求斜边的方法,就获取了两个点之间的直线距离,dx是横坐标x的差值,dy是纵坐标y的差值,再对两个差值的平方和开平方,就是所求的两点之间的距离了。
定义两条直线的中间点变量midpoint,是pointf类型
(3)处理滑动事件
a.图片拖动
获取当前滑动的x坐标和y坐标与开始点x和y坐标的差值,dx是横坐标x差值,dy是纵坐标y的差值,调用matrix.set(currentmaritx)设置在当前位置的基础上移动,matrix.posttranslate(dx,dy)表示矩阵横坐标和纵坐标分别移动dx和dy的距离;
b.图片放大缩小
调用distance获取当前手指滑动的距离enddis,scale是最后移动的距离和开始距离的比值,表示缩放倍数,设置matrix.set(currentmaritx)矩阵为在当前缩放的基础上继续缩放,
matrix.postscale(scale,scale,midpoint.x,midpoint.y)表示设置矩阵进行x轴和y轴进行缩放,缩放的中心点为两个手指的中间点midpoint,最后调用setimagematrix(matrix)设置计算好的矩阵值,界面的图片就会显示缩放的效果了。
(4)抬起事件motionevent.action_pointer_up和motionevent.action_up
抬起手指的时候,设置mode的值为无效的0值。
本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。