栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

基于Android 实现图片平移、缩放、旋转同时进行

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于Android 实现图片平移、缩放、旋转同时进行

前言

之前因为项目需求,其中使用到了图片的单击显示取消,图片平移缩放功能,昨天突然想再加上图片的旋转功能,在网上看了很多相关的例子,可是没看到能同时实现我想要的功能的。

需求:

(1)图片平移、缩放、旋转等一系列操作后,图片需要自动居中显示。

(2)图片旋转后选自动水平显示或者垂直显示

(3)图片在放大缩小的同时都能旋转

Demo实现部分效果截图

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;

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;
  
  private final int ZOOM = 2;
  
  private int mode = NONE;
  
  private Matrix matrix = new Matrix();
  
  private Matrix savedMatrix = new Matrix();
  
  private Matrix matrix1 = new Matrix();
  
  private int displayHeight;
  
  private int displayWidth;
  
  protected float minScale = 1f;
  
  protected float maxScale = 3f;
  
  protected float currentScale = 1f;
  
  private float oldDist;
  
  private float oldRotation = 0;
  
  protected float rotation = 0;
  
  private int imgWidth;
  
  private int imgHeight;
  
  protected final int MOVE_MAX = 2;
  
  private int fingerNumMove = 0;
  private Bitmap bm;
  
  private float matrixScale= 1;
  
  
  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();
    //显示网络图片时使用
    
  }
  @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(); // 回收图片所占的内存
      System.gc(); // 提醒系统及时回收
    }
  }
  
  private void showImage() {
    imgWidth = bm.getWidth();
    imgHeight = bm.getHeight();
    mImageView.setImageBitmap(bm);
    matrix.setScale(1, 1);
    centerAndRotate();
    mImageView.setImageMatrix(matrix);
  }
  
  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("缩放倍数---" + currentScale);
 System.out.println("旋转角度---" + rotation);
 
 matrix1.postScale(currentScale, currentScale, pointM.x, pointM.y);
 
 matrix1.postRotate(rotation, displayWidth / 2, displayHeight / 2);
 break;
    }
  }
  
  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);
  }
  
  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);
  }
  
  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);
  }
  
  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;
      }
    }
  }
  
  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;
    }
  }
  
  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));
    }
    
    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;

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
  }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/163981.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号