Android开发ImageView控件缩放图片(一)

本文介绍了在Android开发中使用ImageView控件配合Matrix进行图片缩放的方法。重点讲解了Matrix的postTranslate和postScale函数,以及如何通过OnTouchListener监听实现平移和缩放操作。文中提到,在ACTION_DOWN时记录初始状态,ACTION_MOVE时计算平移和缩放参数,ACTION_UP时重置状态。最后,文章预告了关于图片缩放限制和平移范围设定的内容。
摘要由CSDN通过智能技术生成

首先还是最基础的ImageView控件如何显示图片:

<ImageView
                android:id="@+id/imgView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:src="@drawable/ic_prepicture"
                android:scaleType="matrix"
                />

以上布局中xml的代码主要是scaleType的设置,决定了图片初始显示的状态, ImageView.ScaleType设置图解 这篇文章可以清楚的看到每个参数的效果。

这里我们主要用matrix这个效果实现缩放,一定要设置scaleType为Matrix,才能实现相应的效果,也可以在代码中imgView.setScaleType(ScaleType.MATRIX);如此设置。

直奔主题

第一步:了解操作对象(Matrix)以及操作方式(平移和缩放)

1,    ImageView控件有getImageMatrix,setImageMatrix这两个函数获取/设置其像素矩阵Matrix;(这个就是我们要操作的对象)

2.1 矩阵Matrix又有如下的函数1:postTranslate(double dx, double dy)可以实现矩阵平移(dx, dy)它的API说明是:Postconcats the matrix with the specified translation. M' = T(dx, dy) * M。

2.2 函数2:postScale(float sx, float sy, float px, float py)  可以实现矩阵水平/垂直方向缩放sx,sy;同时控制缩放的中心点(px, py)API说明:Postconcats the matrix with the specified scale. M' = S(sx, sy, px, py) * M

第二步:了解如何获取平移参数值(dx, dy)以及缩放参数值(sx, sy, centerPoint.x, centerPoint.y)

对于Android开发来说,这样的实现应该很简单,只是一个OnTouchListener类的实现,重写public boolean onTouch(View v, MotionEvent event) 函数,其中平移是单指,缩放是多指

1, switch(event.getAction() & MotionEvent.ACTION_MASK),与MotionEvent.ACTION_MASK做与运算主要是为了多指消息的识别,不然不能响应多指。

2, 平移情况:比较简单,直接在ACTION_MOVE实现中计算dx, dy(event.getX(), event.getY());

3, 缩放情况:需要计算两个手指之间的距离dis1, dis2, 这样scale = dis2/dis1; 同时还要算出两个手指的中心点,作为缩放的中心点。

4,再次理一下思路:当出发Down的消息(手指按下)时候,记录初始点的状态;当响应Move的时候,将当前状态与初始状态作比较,做平移或者缩放的操作;当up的时候,初始化状态。

第三步,通过前面的赘述,直接上代码:

@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		switch(event.getAction() & MotionEvent.ACTION_MASK)
		{
		//单指按下
		case MotionEvent.ACTION_DOWN:
		{
		    mMode = DRAGMODE;
		    mStarPt.set(event.getX(), event.getY());
		    mCurrMatrix = mImageView.getImageMatrix();
		    
		    break;
		}
		//多指缩放的按下
		case MotionEvent.ACTION_POINTER_DOWN:
		{
			mMode = ZOOMMODE;
			mStarDis = GetDistance(event);
			mMidPt   = GetMidPt(event);
			mCurrMatrix = mImageView.getImageMatrix();
			break;
		}
		//移动
		case MotionEvent.ACTION_MOVE:
		{
			if(mMode == DRAGMODE)
			{
				float left = 0, top = 0, right = 0, bottom = 0;
				float dx = event.getX() - mStarPt.x;
				float dy = event.getY() - mStarPt.y;
				
				mMatrix.set(mCurrMatrix);
				mMatrix.postTranslate(dx, dy);
				mStarPt.set(event.getX(), event.getY());
			}
			else if(mMode == ZOOMMODE)
			{
				float endDis = GetDistance(event);
				if (endDis > 10f)
				{
					float fScale = endDis /mStarDis;
					mMatrix.set(mCurrMatrix);
					
					mMatrix.postScale(fScale, fScale, mMidPt.x, mMidPt.y);
					//注意加上这一句,否则缩放为数量级了
					mStarDis = endDis;
				}
			}
			mImageView.setImageMatrix(mMatrix);
			break;
		}
		//单指抬起
		case MotionEvent.ACTION_UP:
		//多指抬起
		case MotionEvent.ACTION_POINTER_UP:
		{
			mMode = 0;
			break;
		}
		
		}
		
		return true;
	}

以下是全局变量的定义:

        private ImageView mImageView;
	private int mMode;    //模式:1-拉动;2-缩放
	final private int DRAGMODE = 1;
	final private int ZOOMMODE = 2;
	
	private PointF   mStarPt = new PointF();
	private float    mStarDis;
	private PointF   mMidPt = new PointF();
	
	private Matrix mMatrix = new Matrix();
	private Matrix mCurrMatrix = new Matrix();

这样就实现了简单的缩放和平移操作了,代码思路还是参考了网上的一些博客文章。

但是,这样还是有一个问题,就是缩放的限制,不能无限大,也不能无限小,平移也需要定义范围内的平移。下一章就要讲如何实现图片浏览器中的效果。到时再将整体代码贴上来。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值