歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android開發ImageView控件縮放圖片

首先還是最基礎的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();

這樣就實現了簡單的縮放和平移操作了,代碼思路還是參考了網上的一些博客文章。
 
但是,這樣還是有一個問題,就是縮放的限制,不能無限大,也不能無限小,平移也需要定義范圍內的平移。下一章就要講如何實現圖片浏覽器中的效果。到時再將整體代碼貼上來。

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved