如何在android中的图像视图上添加图钉标记
Posted
技术标签:
【中文标题】如何在android中的图像视图上添加图钉标记【英文标题】:how to add a pin marker on image view in android 【发布时间】:2012-12-08 21:44:40 【问题描述】:我正在做一个项目,我需要在图像视图上添加引脚,如下图所示。 我们怎么能这样做。
我使用成功创建了一个可缩放的图像视图
TouchImageview.java
class TouchImageView extends ImageView
Matrix matrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
public TouchImageView(Context context)
super(context);
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix.setTranslate(1f, 1f);
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(new OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
mScaleDetector.onTouchEvent(event);
Log.e("Deepak", "X" + event.getRawX());
Log.e("Deepak", "Y" + event.getRawY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG)
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * saveScale);
float scaleHeight = Math.round(origHeight * saveScale);
if (scaleWidth < width)
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
else if (scaleHeight < height)
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
else
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
break;
case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
);
@Override
public void setImageBitmap(Bitmap bm)
super.setImageBitmap(bm);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
public void setMaxZoom(float x)
maxScale = x;
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
@Override
public boolean onScaleBegin(ScaleGestureDetector detector)
mode = ZOOM;
return true;
@Override
public boolean onScale(ScaleGestureDetector detector)
float mScaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale)
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
else if (saveScale < minScale)
saveScale = minScale;
mScaleFactor = minScale / origScale;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
if (origWidth * saveScale <= width || origHeight * saveScale <= height)
matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
if (mScaleFactor < 1)
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1)
if (Math.round(origWidth * saveScale) < width)
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
else
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
else
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (mScaleFactor < 1)
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
return true;
@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
//Fit to screen.
float scale;
float scaleX = (float)width / (float)bmWidth;
float scaleY = (float)height / (float)bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
// Center the image
redundantYSpace = (float)height - (scale * (float)bmHeight) ;
redundantXSpace = (float)width - (scale * (float)bmWidth);
redundantYSpace /= (float)2;
redundantXSpace /= (float)2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = width - 2 * redundantXSpace;
origHeight = height - 2 * redundantYSpace;
right = width * saveScale - width - (2 * redundantXSpace * saveScale);
bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
setImageMatrix(matrix);
现在我需要在上面添加标记。 任何帮助。
【问题讨论】:
我搜索并找到了***.com/questions/13679189/…,但没有得到解决方案 那么你能把它们画在你得到的图像上并保存为新的位图吗? @vodich 好的,但是如何将点击事件添加到标记(我试过了。但在创建单个位图后点击事件出现问题)。 @CommonsWare 你知道怎么做吗 【参考方案1】:我在这里找到了答案https://github.com/catchthecows/androidImageMap
在 Android 视图中实现类似 html 地图的元素:
支持图像作为可绘制或布局中的位图 允许在 xml 中列出区域标签 允许对资源 xml 使用剪切和粘贴 HTML 区域标签(即,能够获取 HTML 地图 - 和图像并在最少编辑的情况下使用它) 如果图像大于设备屏幕,则支持平移 支持捏合缩放 支持点击区域时的回调。 支持将注释显示为气泡文本,并在点击气泡时提供回调【讨论】:
【参考方案2】:我使用过 AndroidImageMap,但我不喜欢它缩放图像的方式,而且您没有将自定义视图添加为可点击区域的功能。
查看这个示例项目https://github.com/jzafrilla/AndroidImageHostpot 我使用https://github.com/chrisbanes/PhotoView/ 来获得缩放和平移功能。
希望这会有所帮助......(对我来说,绝对是的)
【讨论】:
我设法用 PhotoView 实现了这个功能。你的代码帮助了我,谢谢。但是,您的方法需要修改 PhotoView 库,这并不是真正必要的:更好的解决方案是将 onMatrixChangeListener 设置为 photoView 并将用于更新坐标的代码放在那里。此外,这是一个看起来很有前途的库。它支持缩放/平移和在图像上添加图钉github.com/davemorrissey/subsampling-scale-image-view以上是关于如何在android中的图像视图上添加图钉标记的主要内容,如果未能解决你的问题,请参考以下文章