近期也是由于项目的原因,所以有机会接触到这边的算法。 此文重点不是怎样实现的思路和原理, 有须要的同事能够借鉴一下

废话不多说,直接上代码:

<span style="font-size:18px;"><span style="font-size:18px;">public class MyImage extends ImageView {

    private DisplayMetrics dm;

    private int bodyImageViewHeight = 0;
private int bodyImageViewWidth = 0; public MyImage(Context context) {
super(context);
} public MyImage(Context context, AttributeSet attrs) {
super(context, attrs);
dm = context.getResources().getDisplayMetrics();
} @Override
public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX();
int y = (int) event.getY(); //初始化各个部位的范围
initParametersForRegion(); if(isTouchPointInTransparent(x, y)) {
Log.e("mcoy", "the point is in transparent area now");
} else {
positionType position = pointToPosition(x, y);
Log.e("mcoy", "the position is " + position);
} return super.onTouchEvent(event);
} private enum positionType{
REGION_FRONT_HAND,
REGION_FRONT_HEAD,
REGION_FRONT_CHEST,
REGION_FRONT_WAIST,
REGION_FRONT_LEG
} private positionType pointToPosition(int x, int y) {
if(x < mHandX1 || x > mHandX2)
return positionType.REGION_FRONT_HAND;
else if (y < mHeadY)
return positionType.REGION_FRONT_HEAD;
else if(y < mChestY)
return positionType.REGION_FRONT_CHEST;
else if(y < mWaistY)
return positionType.REGION_FRONT_WAIST;
else
return positionType.REGION_FRONT_LEG;
} /**
*
* @param x
* @param y
* @return 推断点击区域是否在透明区域
*/
private boolean isTouchPointInTransparent(int x, int y) { int paddingLeft = this.getPaddingLeft();
int paddingTop = this.getPaddingTop(); int imageHeight = this.getHeight();
int imageWidth = this.getWidth(); Drawable drawable = this.getDrawable();
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); int intrinsicHeight = drawable.getIntrinsicHeight();
int intrinsicWidth = drawable.getIntrinsicWidth(); int locationInBitmapX = (x - paddingLeft) * intrinsicWidth / imageWidth;
int locationInBitmapY = (y - paddingTop) * intrinsicHeight / imageHeight; int pixel = bitmap.getPixel(locationInBitmapX, locationInBitmapY); Log.e("mcoy", "x is " + x);
Log.e("mcoy", "y is " + y);
Log.e("mcoy", "imageHeight is " + imageHeight);
Log.e("mcoy", "imageWidth is " + imageWidth);
Log.e("mcoy", "intrinsicHeight is " + intrinsicHeight);
Log.e("mcoy", "intrinsicWidth is " + intrinsicWidth);
Log.e("mcoy", "locationInBitmapX is " + locationInBitmapX);
Log.e("mcoy", "locationInBitmapY is " + locationInBitmapY);
Log.e("mcoy", "actualBitmapX is " + locationInBitmapX / dm.density);
Log.e("mcoy", "actualBitmapY is " + locationInBitmapY / dm.density);
Log.e("mcoy", "pixel is " + pixel); return pixel == 0;
} private int mHeadY;
private int mHandX1;
private int mHandX2;
private int mChestY;
private int mWaistY; //下面数据须要同UI同事沟通好每一个部位定义的范围。或者自己手动量一下
private final int HEAD_AREA = 130;
private final int LEFT_HAND_AREA = 126;
private final int RIGHT_HAND_AREA = 280;
private final int CHEST_AREA = 260;
private final int WAIST_AREA = 417; private void initParametersForRegion() { if(bodyImageViewHeight != this.getHeight()) { bodyImageViewHeight = this.getHeight();
bodyImageViewWidth = this.getWidth();
int imageIntrinsicHeight = this.getDrawable().getIntrinsicHeight();
int imageIntrinsicWidht = this.getDrawable().getIntrinsicWidth();
Log.e("danny", "bodyImageViewHeight is " + bodyImageViewHeight);
Log.e("danny", "bodyImageViewWidth is " + bodyImageViewWidth);
Log.e("danny", "imageIntrinsicHeight is " + imageIntrinsicHeight);
Log.e("danny", "imageIntrinsicWidht is " + imageIntrinsicWidht); mHeadY = DensityUtil.dip2px(getContext(), HEAD_AREA) * bodyImageViewHeight / imageIntrinsicHeight
+ this.getPaddingTop();
mHandX1 = DensityUtil.dip2px(getContext(), LEFT_HAND_AREA) * bodyImageViewWidth / imageIntrinsicWidht
+ this.getPaddingLeft();
mHandX2 = DensityUtil.dip2px(getContext(), RIGHT_HAND_AREA) * bodyImageViewWidth / imageIntrinsicWidht
+ this.getPaddingLeft();
mChestY = DensityUtil.dip2px(getContext(), CHEST_AREA) * bodyImageViewHeight / imageIntrinsicHeight
+ this.getPaddingTop();
mWaistY = DensityUtil.dip2px(getContext(), WAIST_AREA) * bodyImageViewHeight / imageIntrinsicHeight
+ this.getPaddingTop(); Log.e("danny", "mHeadY is " + mHeadY);
Log.e("danny", "mHandX1 is " + mHandX1);
Log.e("danny", "mHandX2 is " + mHandX2);
Log.e("danny", "mChestY is " + mChestY);
Log.e("danny", "mWaistY is " + mWaistY); }
}
}</span></span>

代码非常easy, 就是一个自己实现的ImageView, 可是有几点须要注意的点:

1 图片须要跟UI同事沟通好对应坐标(认真看完代码之后就会知道原因), 假设换图片的话。那HEAD_AREA等值可能须要又一次定义

2 算法思路---在不同的desity的的设备上。 我们都能够算出图片相应的drawable的width/height,而图片缩放或者是放大是依照比例缩放/放大, 因此我们能够得出例如以下等式:

touchX / imageWidth = positonInBitmap / drawable.getIntransicWidth ;

==> positonInBitmap = touchX * drawable.getIntransicWidth / imageWidth;

touchX是点击在ImageView上的x坐标;imageWidth是图片的宽度。positionInBitmap是touchX映射在ImageView所相应drawable上的x坐标(这句话有点拗口,能够细致想一下)

下面是xml文件:

<span style="font-size:18px;"><span style="font-size:18px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.mcoy.pixelinbitmaptest.MainActivity" > <TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:text="@string/hello_world" /> <com.example.jiangxinxing.views.MyImage
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/man_front"
android:layout_below="@+id/tv" /> </RelativeLayout></span></span>

也有一点须要注意:

须要将adjustViewBounds属性设置为true。这样会调整ImageView的界限来保持图像纵横比不变

demo下载链接:http://download.csdn.net/detail/zxm317122667/9000969

自己定义ImageView,实现点击之后算出点击的是身体的哪个部位的更多相关文章

  1. Android 自己定义ImageView实现圆角/圆形 附加OnTouchListener具体凝视以及Button圆角

    转载请注明出处:王亟亟的大牛之路 平时要用一些非方方正正的button之类的小伙伴们是怎样实现的?RadioButton? ImageButton? 还是其它? 今天亟亟上的是ImageView来实现 ...

  2. 实现RecycleView动态使列表item可以点击或不可点击切换

    效果 这里讲的是第二个button跳转的Activity,这里和上一篇不同之处在于可以item点击.item子控件点击 继承BaseAdapter 同样也要继承BaseAdapter public c ...

  3. 利用Kotlin扩展函数实现任意View的点击处理(点击效果和防止快速点击)

    利用Kotlin扩展函数实现View的点击处理(点击效果和防止快速点击) kotlin经典写法: view?.setOnClickListener { //实现 } 项目实践证明,这种写法存在问题 例 ...

  4. 点击li,点击的li添加class,其余去掉class

    点击li,点击的li添加class,其余去掉class <script type="text/javascript"> $(function () { var liob ...

  5. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验三:按键模块② — 点击与长点击

    实验三:按键模块② - 点击与长点击 实验二我们学过按键功能模块的基础内容,其中我们知道按键功能模块有如下操作: l 电平变化检测: l 过滤抖动: l 产生有效按键. 实验三我们也会z执行同样的事情 ...

  6. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验五:按键模块④ — 点击,长点击,双击

    实验五:按键模块④ - 点击,长点击,双击 实验二至实验四,我们一共完成如下有效按键: l 点击(按下有效) l 点击(释放有效) l 长击(长按下有效) l 双击(连续按下有效) 然而,不管哪个实验 ...

  7. jquery对类的操作,添加,删除,点击添加,再点击删除

    jquery对类的操作,添加(addClass),删除l类(remoceClass),点击添加,再点击删除(toggleClass)

  8. C# Chart 点击获取当前点击坐标和Series

    C# Chart 点击获取当前点击坐标和Series https://blog.csdn.net/wumuzhizi/article/details/47168989 2015年07月31日 13:5 ...

  9. input radio点击选中再点击取消

    这里主要说一下这个jquery中的data()方法,个人感觉这个方法平时挺少用到的,所以说一说,按照官方的解释就是 向元素附加数据,然后取回该数据; 嗯,是的,就是这么简单. 那这里说一下这个方法的使 ...

随机推荐

  1. SQL 与或运算

    如果一个字段需要同时包含多个信息点, 最佳的方法是进行位运算,如:1,2,4,8,16 根据与运算进行判断,如一个字段为7,判断2是否存在, 7&2 = 2为ture时,表示存在,反之亦然, ...

  2. AtCoder Grand Contest 021

    A - Digit Sum 2 Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Find t ...

  3. 【Luogu】P2254瑰丽华尔兹(堆优化DP)

    题目链接 我也不知道为什么脑子一抽就想了个堆优化……然后贼慢…… 因为上午听不懂wys的电音专场(快速傅立叶变换),然后就做了这么一道题. 首先朴素DP很sb都能秒出.就是枚举时刻.位置(两维)然后转 ...

  4. 移动端可拖动导航菜单小demo

    <!DOCTYPE html> <html lang="en"> <head> <title>移动端滑动导航菜单</title ...

  5. 刷题总结——怪题(ssoj费用流)

    题目: 题目描述 给出一个长度为 n 的整数序列 hi ,现在要通过一些操作将这个序列修改为单调不降序列,即  hi≤hi+1 . 可以用的操作有 m 种,第 i 种操作可以通过支付 ci 的代价将一 ...

  6. freemarker实现自定义指令和自定义函数

    自定义指令: 1.指令在前台实现 <#macro name param1,param2,param3...paramN> </#macro> 2.指令在后台实现 1.实现Tem ...

  7. Codevs 3287 货车运输 == 洛谷P1967

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编 ...

  8. 【NOIP2016练习】T2 跑跑步 (数论)

    : 这场的难度是从高到低的 ..]of longint; n,m,i,ans:longint; function gcd(x,y:longint):longint; var r:longint; be ...

  9. jquery 同源跨域请求整理

    //同源ajax请求数据 function getData(url,paramjson,fn) { $.ajax({ type : "POST", //提交方式 url : url ...

  10. XSD(XML Schema Definition)学习笔记

    今天学习了XSD相关的知识,为了以后查找的方便,写一些笔记. 一.什么是XSD? 1.XSD全称:XML Schema Definition.XML Schema 的作用是定义 XML 文档的合法构建 ...