欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Android 實(shí)現(xiàn)圖片平移、縮放、旋轉(zhuǎn)同時(shí)進(jìn)行

 更新時(shí)間:2015年11月18日 10:10:24   投稿:mrr  
這篇文章主要介紹了基于Android 實(shí)現(xiàn)圖片平移、縮放、旋轉(zhuǎn)同時(shí)進(jìn)行的相關(guān)資料,需要的朋友可以參考下

前言

之前因?yàn)轫?xiàng)目需求,其中使用到了圖片的單擊顯示取消,圖片平移縮放功能,昨天突然想再加上圖片的旋轉(zhuǎn)功能,在網(wǎng)上看了很多相關(guān)的例子,可是沒看到能同時(shí)實(shí)現(xiàn)我想要的功能的。

需求:

(1)圖片平移、縮放、旋轉(zhuǎn)等一系列操作后,圖片需要自動(dòng)居中顯示。

(2)圖片旋轉(zhuǎn)后選自動(dòng)水平顯示或者垂直顯示

(3)圖片在放大縮小的同時(shí)都能旋轉(zhuǎn)

Demo實(shí)現(xiàn)部分效果截圖

Demo主要代碼

Java

MainActivity.java
package com.practice.noyet.rotatezoomimageview;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import com.ypy.eventbus.EventBus;
import java.io.File;
import java.math.BigDecimal;
/**
* package: com.practice.noyet.rotatezoomimageview
* Created by noyet on 2015/11/11.
*/
public class MainActivity extends Activity implements View.OnTouchListener {
  private ImageView mImageView;
  private PointF point0 = new PointF();
  private PointF pointM = new PointF();
  private final int NONE = 0;
  /**
   * 平移
   */
  private final int DRAG = 1;
  /**
   * 旋轉(zhuǎn)、縮放
   */
  private final int ZOOM = 2;
  /**
   * 設(shè)定事件模式
   */
  private int mode = NONE;
  /**
   * 圖片縮放矩陣
   */
  private Matrix matrix = new Matrix();
  /**
   * 保存觸摸前的圖片縮放矩陣
   */
  private Matrix savedMatrix = new Matrix();
  /**
   * 保存觸點(diǎn)移動(dòng)過程中的圖片縮放矩陣
   */
  private Matrix matrix1 = new Matrix();
  /**
   * 屏幕高度
   */
  private int displayHeight;
  /**
   * 屏幕寬度
   */
  private int displayWidth;
  /**
   * 最小縮放比例
   */
  protected float minScale = 1f;
  /**
   * 最大縮放比例
   */
  protected float maxScale = 3f;
  /**
   * 當(dāng)前縮放比例
   */
  protected float currentScale = 1f;
  /**
   * 多點(diǎn)觸摸2個(gè)觸摸點(diǎn)間的起始距離
   */
  private float oldDist;
  /**
   * 多點(diǎn)觸摸時(shí)圖片的起始角度
   */
  private float oldRotation = 0;
  /**
   * 旋轉(zhuǎn)角度
   */
  protected float rotation = 0;
  /**
   * 圖片初始寬度
   */
  private int imgWidth;
  /**
   * 圖片初始高度
   */
  private int imgHeight;
  /**
   * 設(shè)置單點(diǎn)觸摸退出圖片顯示時(shí),單點(diǎn)觸摸的靈敏度(可針對不同手機(jī)單獨(dú)設(shè)置)
   */
  protected final int MOVE_MAX = 2;
  /**
   * 單點(diǎn)觸摸時(shí)手指觸發(fā)的‘MotionEvent.ACTION_MOVE'次數(shù)
   */
  private int fingerNumMove = 0;
  private Bitmap bm;
  /**
   * 保存matrix縮放比例
   */
  private float matrixScale= 1;
  /*private String imagePath;*/
  /**
   * 顯示被存入緩存中的網(wǎng)絡(luò)圖片
   *
   * @param event 觀察者事件
   */
  public void onEventMainThread(CustomEventBus event) {
    if (event == null) {
      return;
    }
    if (event.type == CustomEventBus.EventType.SHOW_PICTURE) {
      bm = (Bitmap) event.obj;
      showImage();
    }
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initData();
  }
  public void initData() {
    // TODO Auto-generated method stub
    bm = BitmapFactory.decodeResource(getResources(), R.drawable.alipay);
    DisplayMetrics dm = getResources().getDisplayMetrics();
    displayWidth = dm.widthPixels;
    displayHeight = dm.heightPixels;
    mImageView = (ImageView) findViewById(R.id.image_view);
    mImageView.setOnTouchListener(this);
    showImage();
    //顯示網(wǎng)絡(luò)圖片時(shí)使用
    /*File file = MainApplication.getInstance().getImageCache()
        .getDiskCache().get(圖片路徑);
    if (!file.exists()) {
      Toast.makeText(this, "圖片路徑錯(cuò)誤", Toast.LENGTH_SHORT).show();
    } else {
      new MyTask().execute(file);
    }*/
  }
  @Override
  public boolean onTouch(View view, MotionEvent event) {
    ImageView imageView = (ImageView) view;
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
        savedMatrix.set(matrix);
        point0.set(event.getX(), event.getY());
        mode = DRAG;
        System.out.println("MotionEvent--ACTION_DOWN");
        break;
      case MotionEvent.ACTION_POINTER_DOWN:
        oldDist = spacing(event);
        oldRotation = rotation(event);
        savedMatrix.set(matrix);
        setMidPoint(pointM, event);
        mode = ZOOM;
        System.out.println("MotionEvent--ACTION_POINTER_DOWN---" + oldRotation);
        break;
      case MotionEvent.ACTION_UP:
        if (mode == DRAG & (fingerNumMove this.finish();
        }
        checkView();
        centerAndRotate();
        imageView.setImageMatrix(matrix);
        System.out.println("MotionEvent--ACTION_UP");
        fingerNumMove = 0;
        break;
      case MotionEvent.ACTION_POINTER_UP:
        mode = NONE;
        System.out.println("MotionEvent--ACTION_POINTER_UP");
        break;
      case MotionEvent.ACTION_MOVE:
        operateMove(event);
        imageView.setImageMatrix(matrix1);
        fingerNumMove++;
        System.out.println("MotionEvent--ACTION_MOVE");
        break;
    }
    return true;
  }
  @Override
  protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    if (bm != null & !bm.isRecycled()) {
      bm.recycle(); // 回收圖片所占的內(nèi)存
      System.gc(); // 提醒系統(tǒng)及時(shí)回收
    }
  }
  /**
   * 顯示圖片
   */
  private void showImage() {
    imgWidth = bm.getWidth();
    imgHeight = bm.getHeight();
    mImageView.setImageBitmap(bm);
    matrix.setScale(1, 1);
    centerAndRotate();
    mImageView.setImageMatrix(matrix);
  }
  /**
   * 觸點(diǎn)移動(dòng)時(shí)的操作
   *
   * @param event 觸摸事件
   */
  private void operateMove(MotionEvent event) {
    matrix1.set(savedMatrix);
    switch (mode) {
      case DRAG:
        matrix1.postTranslate(event.getX() - point0.x, event.getY() - point0.y);
        break;
      case ZOOM:
        rotation = rotation(event) - oldRotation;
        float newDist = spacing(event);
        float scale = newDist / oldDist;
        currentScale = (scale > 3.5f) ? 3.5f : scale;
        System.out.println("縮放倍數(shù)---" + currentScale);
        System.out.println("旋轉(zhuǎn)角度---" + rotation);
        /** 縮放 */
        matrix1.postScale(currentScale, currentScale, pointM.x, pointM.y);
        /** 旋轉(zhuǎn) */
        matrix1.postRotate(rotation, displayWidth / 2, displayHeight / 2);
        break;
    }
  }
  /**
   * 兩個(gè)觸點(diǎn)的距離
   *
   * @param event 觸摸事件
   * @return float
   */
  private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
  }
  /**
   * 獲取旋轉(zhuǎn)角度
   */
  private float rotation(MotionEvent event) {
    double delta_x = (event.getX(0) - event.getX(1));
    double delta_y = (event.getY(0) - event.getY(1));
    double radians = Math.atan2(delta_y, delta_x);
    return (float) Math.toDegrees(radians);
  }
  /**
   * 兩個(gè)觸點(diǎn)的中間坐標(biāo)
   *
   * @param pointM 中間坐標(biāo)
   * @param event 觸摸事件
   */
  private void setMidPoint(PointF pointM, MotionEvent event) {
    float x = event.getX(0) + event.getY(1);
    float y = event.getY(0) + event.getY(1);
    pointM.set(x / 2, y / 2);
  }
  /**
   * 檢查約束條件(縮放倍數(shù))
   */
  private void checkView() {
    if (currentScale > 1) {
      if (currentScale * matrixScale > maxScale) {
        matrix.postScale(maxScale / matrixScale, maxScale / matrixScale, pointM.x, pointM.y);
        matrixScale = maxScale;
      } else {
        matrix.postScale(currentScale, currentScale, pointM.x, pointM.y);
        matrixScale *= currentScale;
      }
    } else {
      if (currentScale * matrixScale else {
        matrix.postScale(currentScale, currentScale, pointM.x, pointM.y);
        matrixScale *= currentScale;
      }
    }
  }
  /**
   * 圖片居中顯示、判斷旋轉(zhuǎn)角度 小于(90 * x + 45)度圖片旋轉(zhuǎn)(90 * x)度 大于則旋轉(zhuǎn)(90 * (x+1))
   */
  private void centerAndRotate() {
    RectF rect = new RectF(0, 0, imgWidth, imgHeight);
    matrix.mapRect(rect);
    float width = rect.width();
    float height = rect.height();
    float dx = 0;
    float dy = 0;
    if (width 2 - width / 2 - rect.left;
    } else if (rect.left > 0) {
      dx = -rect.left;
    } else if (rect.right if (height 2 - height / 2 - rect.top;
    } else if (rect.top > 0) {
      dy = -rect.top;
    } else if (rect.bottom if (rotation != 0) {
      int rotationNum = (int) (rotation / 90);
      float rotationAvai = new BigDecimal(rotation % 90).setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
      float realRotation = 0;
      if (rotation > 0) {
        realRotation = rotationAvai > 45 ? (rotationNum + 1) * 90 : rotationNum * 90;
      } else if (rotation 0) {
        realRotation = rotationAvai 45 ? (rotationNum - 1) * 90 : rotationNum * 90;
      }
      System.out.println("realRotation: " + realRotation);
      matrix.postRotate(realRotation, displayWidth / 2, displayHeight / 2);
      rotation = 0;
    }
  }
  /**
   * 顯示網(wǎng)絡(luò)圖片時(shí)使用
   */
  private class MyTask extends AsyncTaskFile, File, Bitmap> {
    Bitmap bitmap;
    String path;
    int scale = 1;
    long size;
    @Override
    protected Bitmap doInBackground(File... params) {
      // TODO Auto-generated method stub
      try {
        size = params[0].length();
        path = params[0].getAbsolutePath();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        scale = calculateInSampleSize(options, displayWidth,
            displayHeight);
        options.inJustDecodeBounds = false;
        options.inSampleSize = scale;
        bitmap = BitmapFactory.decodeFile(path, options);
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      return bitmap;
    }
    @Override
    protected void onPostExecute(Bitmap result) {
      // TODO Auto-generated method stub
      EventBus.getDefault().post(
          new CustomEventBus(CustomEventBus.EventType.SHOW_PICTURE, result));
    }
    /**
     * 獲取圖片縮放比例
     *
     * @param paramOptions Options
     * @param paramInt1  寬
     * @param paramInt2  高
     * @return int
     */
    private int calculateInSampleSize(BitmapFactory.Options paramOptions,
                     int paramInt1, int paramInt2) {
      int i = paramOptions.outHeight;
      int j = paramOptions.outWidth;
      int k = 1;
      if ((i > paramInt2) || (j > paramInt1)) {
        int m = Math.round(i / paramInt2);
        int n = Math.round(j / paramInt1);
        k = m return k;
    }
  }
}
CustomEventBus.java
package com.practice.noyet.rotatezoomimageview;
/**
* package: com.practice.noyet.rotatezoomimageview
* Created by noyet on 2015/11/11.
*/
public class CustomEventBus {
  public EventType type;
  public Object obj;
  public CustomEventBus(EventType type, Object obj) {
    this.type = type;
    this.obj = obj;
  }
  enum EventType {
    SHOW_PICTURE
  }
}

相關(guān)文章

  • Android 調(diào)用設(shè)備已有的相機(jī)應(yīng)用詳情

    Android 調(diào)用設(shè)備已有的相機(jī)應(yīng)用詳情

    這篇文章主要介紹了Android 調(diào)用設(shè)備已有的相機(jī)應(yīng)用,如果我們只是需要讓用戶能夠拍攝照片,則可以直接請求已有相機(jī)應(yīng)用拍攝照片并將照片返回給我們,下面我們一起來看看這些功能,需要的朋友可以參考一下
    2021-10-10
  • 實(shí)例講解Android中SQLiteDatabase使用方法

    實(shí)例講解Android中SQLiteDatabase使用方法

    這篇文章主要以一個(gè)簡單的實(shí)例為大家詳細(xì)講解Android中SQLiteDatabase使用方法,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android?Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼

    Android?Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼

    本文將通過實(shí)現(xiàn)一個(gè)canvas繪制斑馬紋類。使用Stack布局,將斑馬紋放在下方作為背景板,需要展示的內(nèi)容在上方。從而實(shí)現(xiàn)?“斑馬紋”背景,感興趣的可以了解一下
    2022-06-06
  • 一款不錯(cuò)的android6.0、7.0權(quán)限管理器推薦

    一款不錯(cuò)的android6.0、7.0權(quán)限管理器推薦

    下面小編就為大家分享一篇一款不錯(cuò)的android6.0、7.0權(quán)限管理器推薦,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Android自定義ViewGroup實(shí)現(xiàn)絢麗的仿支付寶咻一咻雷達(dá)脈沖效果

    Android自定義ViewGroup實(shí)現(xiàn)絢麗的仿支付寶咻一咻雷達(dá)脈沖效果

    這篇文章主要介紹了Android自定義ViewGroup實(shí)現(xiàn)絢麗的仿支付寶咻一咻雷達(dá)脈沖效果的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 解析Android框架之Volley源碼

    解析Android框架之Volley源碼

    我們知道Volley是在2013年Google I/O大會(huì)上推出了一個(gè)新的網(wǎng)絡(luò)通信框架,他的設(shè)計(jì)目的就是為了那些請求數(shù)據(jù)量不是特別大,但是又是特別頻繁的網(wǎng)絡(luò)操作非常適合。但是對于數(shù)據(jù)量較大的請求,比如說下載一個(gè)較大的文件,Volley可能相比于其他的框架,就有點(diǎn)不足了。
    2021-06-06
  • Android 仿微信朋友圈點(diǎn)贊和評論彈出框功能

    Android 仿微信朋友圈點(diǎn)贊和評論彈出框功能

    這篇文章主要介紹了Android 仿微信朋友圈點(diǎn)贊和評論彈出框功能的相關(guān)資料,非常不錯(cuò),具有參考解決價(jià)值,需要的朋友可以參考下
    2016-11-11
  • Android Studio配置(Android Studio4.1為例)

    Android Studio配置(Android Studio4.1為例)

    這篇文章主要介紹了Android Studio配置(Android Studio4.1為例),文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Flutter?Widget之FutureBuilder使用示例詳解

    Flutter?Widget之FutureBuilder使用示例詳解

    這篇文章主要為大家介紹了Flutter?Widget之FutureBuilder使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Android SQLite數(shù)據(jù)庫連接實(shí)現(xiàn)登錄功能

    Android SQLite數(shù)據(jù)庫連接實(shí)現(xiàn)登錄功能

    這篇文章主要為大家詳細(xì)介紹了Android SQLite數(shù)據(jù)庫連接實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10

最新評論