关于Matrix在项目中出现过的一些小问题


今天在项目中测试头像截取功能时候出现了的小bug
bug如下:调用手机相机照完相截取完图片以后,那个matrix的取景框本来是在整个imageview的中间,第一次进行手势操作屏幕 matrix就会跳到imageview的下面去。而且对照片进行缩放以后也会出现这样的情况。
这时候 我们只需要把matrix.set(startMatrix);改为matrix.set(savedMatrix);
这样的话我们每次进行操作的结果都是得到正确的保存。
关于第一次对截屏照片进行触摸等手势操作,整个矩阵取景框会跳到最下面是因为默认情况下矩阵取景框就是最下面的,我们要在oncreate()中,把图片的位置相对于imageview的左上角往右往下各偏移left个像素 matrix.postTranslate(120, 300);,那样的话 矩阵的相对位置的中心点就会跟整个屏幕重合。
package com.yuemao.live.activity.wode;

import java.io.IOException;

import javax.swing.text.AbstractDocument.Content;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.ImageLoader;
import com.yuemao.live.R;
import com.yuemao.live.activity.base.BaseActivity;
import com.yuemao.live.activity.base.MyApplication;
import com.yuemao.live.constants.Constants;
import com.yuemao.live.util.AndroidUtil;
import com.yuemao.live.util.FileUtil;
import com.yuemao.live.util.ImageUtil;
import com.yuemao.live.util.ScreenShotUtil;
import com.yuemao.live.view.Crop_Canvas;
import com.yuemao.live.view.dialog.BasicDialog;
/**
 * 截取头像
 * @author zs
 * 2014-6-15
 */
public class CutImageActivity extends BaseActivity implements OnClickListener{

 private Crop_Canvas canvas = null;

 private static final int NONE = 0;
 private static final int DRAG = 1;
 private static final int ZOOM = 2;
 
 private int mode = NONE;
 private float oldDist;
 private Matrix matrix = new Matrix();
 private Matrix savedMatrix = new Matrix();
 private Matrix startMatrix = new Matrix();
 private PointF start = new PointF();
 private PointF mid = new PointF();
 public static CutImageActivity instance;
 private boolean isFirst = true;//第一次保存起来
 private int phoneHeight;
 private int statusBarHeight;
 private int phoneWidth;
 private MyApplication application;
 
 private String flag;//0:初始化,1:更新头像
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wode_person_icon_cut);
        if(util.getPhoneHeight()== 0){
         AndroidUtil.getScreen(this, util);
        }
        flag = getIntent().getStringExtra("flag");
        application = MyApplication.getInstance();
        phoneHeight = util.getPhoneHeight();
        phoneWidth = util.getPhoneWidth();
        statusBarHeight = util.getStateHeight();
        instance = this;
       //新增
        matrix.postTranslate(120, 300);
        this.init();
    }
   
    @Override
 protected void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  if(dialog != null && dialog.isShowing()){
   dialog.dismiss();
   dialog = null;
  }
 }

    /**
     * 初始化
     */
    private void init(){
     isFirst = true;
     canvas = (Crop_Canvas)findViewById(R.id.myCanvas);
     canvas.setOnTouchListener(new OnTouchListener() {
   public boolean onTouch(View v, MotionEvent event) {
    ImageView view = (ImageView) v;
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:// 单点
     if(isFirst){

      isFirst = false;
      
      startMatrix.set(matrix);
      
     }
     savedMatrix.set(matrix); // 把原始 Matrix对象保存起来
     
     start.set(event.getX(), event.getY()); // 设置x,y坐标
     mode = DRAG;
     break;
    case MotionEvent.ACTION_UP:// 单点弹起
    case MotionEvent.ACTION_POINTER_UP:// 多点弹起
     mode = NONE;
     break;
    case MotionEvent.ACTION_POINTER_DOWN:// 多点
     oldDist = spacing(event);
     savedMatrix.set(matrix);
     midPoint(mid, event); // 求出手指两点的中点
     mode = ZOOM;
     break;
    case MotionEvent.ACTION_MOVE:// 按下且在拖动
     if(mode == DRAG){
      //新增
      matrix.set(savedMatrix);
      matrix.postTranslate(event.getX() - start.x,event.getY() - start.y);
     }else if (mode == ZOOM){
      float newDist = spacing(event);
      if(newDist > 10f){
       matrix.set(savedMatrix);
       float scale = newDist / oldDist;
       matrix.postScale(scale, scale, mid.x, mid.y);
       
      }
     }
     break;
    }

    view.setImageMatrix(matrix);
    center(true,false);
    matrixCheck();
    return true;
   }

   // 求两点距离
   private float spacing(MotionEvent event){
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
   }

   // 求两点间中点
   private void midPoint(PointF point, MotionEvent event){
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
   }
  });
     canvas.setMyBitmap(application.getCutBefore(),phoneHeight,phoneWidth,statusBarHeight,util.getBackLayoutHeight(),util.getCutIconLeft());//源图片
    }
    /**
  * 检查是否可以再变化
  * 图片4个顶点的坐标
  */
 private void matrixCheck(){
  float[] f = new float[9];
  double width ;
  matrix.getValues(f);
  float x1 = f[0] * 0 + f[1] * 0 + f[2];
  float y1 = f[3] * 0 + f[4] * 0 + f[5];
  float x2 = f[0] * application.getCutBefore().getWidth() + f[1] * 0 + f[2];
  float y2 = f[3] * application.getCutBefore().getWidth() + f[4] * 0 + f[5];
  width = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));//图片现宽度
  if (width < util.getCutIconWidth()){//缩放比率判断
   matrix.set(savedMatrix);
  }
 }
    /**
     * 居中控制
     top = (phoneHeight-statusBarHeight-height-backLayout)/2;
     */

    private void center(boolean horizontal, boolean vertical) {
  Matrix m = new Matrix();
  m.set(matrix);
  RectF rect = null;
  rect = new RectF(0, 0, application.getCutBefore().getWidth(), application.getCutBefore().getHeight());
  
  m.mapRect(rect);
  float height = rect.height();
  float width = rect.width();
  float deltaX = 0, deltaY = 0;
  if(vertical){//手机屏幕分辨率的高度
   if (height < phoneHeight) {
    deltaY = (phoneHeight - height-statusBarHeight-util.getBackLayoutHeight()) / 2 - rect.top;
   } else if (rect.top > 0) {
    deltaY = -rect.top;
   } else if (rect.bottom < phoneHeight) {
    deltaY = canvas.getHeight() - rect.bottom;
   }
  }

  if(horizontal){ //手机屏幕分辨率的宽度
   if (width < phoneWidth) {
    deltaX = (phoneWidth - width) / 2 - rect.left;
   } else if (rect.left > 0) {
    deltaX = -rect.left;
   } else if (rect.right < phoneWidth) {
    deltaX = phoneWidth - rect.right;
   }
  }
  matrix.postTranslate(deltaX, deltaY);
 }
    private Dialog dialog;
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  switch(v.getId()){
  case R.id.title_btn_left_layout:
   if(application.getCutBefore()!=null){
    application.getCutBefore().recycle();
    application.setCutBefore(null);
   }
   finish();
   break;
  case R.id.title_btn_right_layout:
   dialog = BasicDialog.loadDialog(CutImageActivity.this,"正在截取").getDialog();
   dialog.show();
   Bitmap b = ScreenShotUtil.takeScreenShot(CutImageActivity.this,statusBarHeight);
   application.getCutBefore().recycle();
   Bitmap save = ImageUtil.zoomImageNoChangeWidth(b,200);
   application.setSureAfter(save);
   String fileName;
   if("1".equals(flag)){//0:初始化,1:更新头像
    ImageLoader.getInstance().clearMemoryCache(); // 清除内存缓存
    ImageLoader.getInstance().clearDiscCache();   // 清除本地缓存
    fileName = util.getUserNo();
   }else{
    fileName = "temp";
   }
   try {//保存到本地
    FileUtil.saveFileSdCard(save, Constants.ICON_PATH ,fileName);
    MyApplication.getInstance().removeCacheImage(Constants.ICON_PATH + fileName+".png");
   } catch (IOException e) {
    e.printStackTrace();
   }
   util.setHeadImgIsUpload(true);
   b.recycle();
   if(dialog != null && dialog.isShowing()){
    dialog.dismiss();
   }
   finish();
   break;
  }
 }
// //create
//  public Matrix getImageMatrix() {
//         return mMatrix;
//     }
// 
// @Override
 protected void findViewById() {
  // TODO Auto-generated method stub
  
 }

 @Override
 protected void initView() {
  // TODO Auto-generated method stub
  
 }
 
}
package com.yuemao.live.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
 * 四个角没有小矩形(即不能拖动)
 * @author zs
 * 2014-6-14
 */
public class Crop_Canvas extends ImageView {

 private Bitmap bitMap = null;    //原始图片
 private RectF src = null;     //经过比例转换后的裁剪区域
 private RectF dst = null;     //图片显示区域,也就是drawBitmap函数中的目标dst
 private RectF ChooseArea = null;   //方框区域    
 private Paint mPaint = null;    //画笔
 private Matrix matrix = null;    //矩阵
 
 private boolean firstFlag = false;          //是否第一次画边框
 
 public static int left,right,top,bottom,width,height;
 public static int statusBarHeight,backLayout;
 private int phoneWidth, phoneHeight;
 
 public Crop_Canvas(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.init();
 }
 
 public Crop_Canvas(Context context) {
  super(context);
  this.init();
 }
 /**
  * 初始化
  */
 public void init(){
  dst = new RectF();
  mPaint = new Paint();
  mPaint.setColor(Color.BLACK);
  mPaint.setAlpha(134);
  mPaint.setStyle(Paint.Style.STROKE);      //将画笔的风格改为空心
  ChooseArea = new RectF();
  
  src = null;
  firstFlag = true;
 }
 /**
  * h:手机高度
  * w:手机宽度
  * sh:状态栏高度
  * l:截图的x左标
  */
 @SuppressWarnings("deprecation")
 public void setMyBitmap(Bitmap bitmap,int h,int w,int sh,int back,int l){
  phoneHeight = h;
  phoneWidth = w;
  statusBarHeight = sh;
  backLayout = back;
  left = l;
  BitmapDrawable bd = new BitmapDrawable(bitmap);
  src = new RectF(0,0,bd.getIntrinsicWidth(),bd.getIntrinsicHeight());
  this.bitMap = bitmap.copy(Config.ARGB_8888, true);
  int traleRight = phoneHeight-statusBarHeight-bitmap.getHeight()-backLayout;
  if(traleRight>0){
   traleRight = traleRight/2;
  }else{
   traleRight = 50;
  }
  matrix = this.getImageMatrix();
  matrix.mapRect(dst, src);
  matrix.postTranslate(left, traleRight); // 图片的位置相对于imageview的左上角往右往下各偏移left个像素
  this.setImageMatrix(matrix);
  this.setImageBitmap(bitMap);
  
 }
 /**
  * 初始化方框
  */
 public void initScaleImage(){
  right = phoneWidth - left;
  width = right -left;
  height = width;//正方形
  
  top = (phoneHeight-statusBarHeight-height-backLayout)/2;
  bottom = top + height;
  dst.set(left,top,right,bottom);
  ChooseArea = new RectF(dst);
 }
 
 /**
  * 重画
  */
 public void onDraw(Canvas canvas){
  super.onDraw(canvas);
  if(firstFlag){
   initScaleImage();
   firstFlag = false;
   mPaint.setColor(Color.WHITE);
  }
  
  canvas.drawRect(ChooseArea, mPaint);
 }
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/fill_fill"
   android:background="@color/color_white">
     <RelativeLayout
         android:id="@+id/bottom_layout"
         android:background="@color/color_black"
         android:layout_alignParentBottom="true"
      style="@style/titlebar_all_layout"
      android:paddingLeft="15dp"
      android:paddingRight="15dp">
      <LinearLayout
          android:id="@+id/title_btn_left_layout"
          style="@style/titlebar_btn_layout_left">
          <TextView
              android:id="@+id/title_btn_left"
              style="@style/titlebar_btn_lright"
              android:textColor="@color/color_white"
              android:text="@string/photo_cannel"/>
      </LinearLayout>
     
      <LinearLayout
          android:id="@+id/title_btn_right_layout"
          style="@style/titlebar_btn_layout_right">
          <TextView
              android:id="@+id/title_btn_right"
              style="@style/titlebar_btn_lright"
              android:text="@string/photo_check"
              android:textColor="@color/color_white"
              android:background="@drawable/main_btn_msg"/>
      </LinearLayout>
  </RelativeLayout>
  <LinearLayout
       android:layout_above="@id/bottom_layout"
    android:background="#000000"
    android:gravity="center_horizontal"
    style="@style/fill_fill">
    <com.yuemao.live.view.Crop_Canvas
        android:id="@+id/myCanvas"
        style="@style/fill_fill"
        android:layout_gravity="center"
      android:scaleType="matrix">
    </com.yuemao.live.view.Crop_Canvas>
  </LinearLayout>
</RelativeLayout>


你可能感兴趣的:(图片,截取,Matrix)