仿微信头像图片裁剪并压缩到100K以下到本地

来源:互联网 发布:常州瑞声科技 知乎 编辑:程序博客网 时间:2024/04/19 14:10
逻辑:1、打开本地相机-并传入path路径
          2、在onActivityResult中,判断File(path)是否为空,不为空则跳转到下个界面
          PS:这里为什么要用path而不用onActivity返回的bitmap对象呢。 因为返回的bitmap对象是没有path路径的图片清晰
          3、利用ClipImageLayout来对图片进行裁剪--并获取到裁剪完毕之后的图片    
     4、对图片进行质量压缩,并保存到本地

     PS:第四部的时候,一定要压缩之后们通过流的方式保存到本地,不要在调用BitmapFactory.decodeStream方法,否则又会回到200K


import java.io.File;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.provider.MediaStore;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity {      private File file; // 要保存的文件sss      private Button btnCamera;      @Override      protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);            setContentView(R.layout. activity_main);             btnCamera = (Button) findViewById(R.id. btn_camera);             btnCamera.setOnClickListener( new OnClickListener() {                   @Override                   public void onClick(View v) {                         file = new File(FileUtils.getImgStorageDirectory() + "/aa.jpg");                        Intent intent = new Intent();                        intent.setAction( "android.media.action.IMAGE_CAPTURE");                        Uri uri = Uri. fromFile(file);                        intent.putExtra(MediaStore. EXTRA_OUTPUT, uri);                        startActivityForResult(intent, 100);                  }            });      }      @Override      protected void onActivityResult( int requestCode, int resultCode, Intent data) {             super.onActivityResult(requestCode, resultCode, data);             if (requestCode == 100 && file.exists() && file.length() > 0) {                   // 这里吧文件的路径传入到下一个界面,就是裁剪的界面                  Intent intent = new Intent(MainActivity. this, CropActivity.class);                  intent.putExtra( "path", file.getPath());                  startActivity(intent);            }      }}第二个界面:裁剪的界面:import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.example.ima.view.ClipImageLayout;public class CropActivity extends Activity implements OnClickListener {      private Button btn;      private ClipImageLayout mClipImageLayout;      private String path;      @Override      protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);            setContentView(R.layout. activity_crop);             path = getIntent().getStringExtra( "path");             btn = (Button) findViewById(R.id. crop_button);             btn.setOnClickListener(CropActivity. this);             mClipImageLayout = (ClipImageLayout) findViewById(R.id.clipImageLayout );             // 有的系统返回的图片是旋转了,有的没有旋转,所以处理             int degreee = ImageUtil. readPictureDegree(path);            Bitmap bitmap = ImageUtil. getSmallBitmap(path);             if (bitmap != null) {                   if (degreee == 0) {                         mClipImageLayout.setImageBitmap(bitmap);                  } else {                         mClipImageLayout.setImageBitmap(ImageUtil. rotaingBitmap(degreee, bitmap));                  }            }      }      @Override      public void onClick(View v) {             //得到裁剪的图片            Bitmap bitmap = mClipImageLayout.clip();            String imageName = String.valueOf(System.currentTimeMillis());             //这里把裁剪过后的图片进行质量压缩,并且保存到本地            ImageUtil. compressAndSave(bitmap, imageName);            Intent intent = new Intent(CropActivity. this, ShowActivity.class);            intent.putExtra( "imageName", imageName);            startActivity(intent);      }}这个类的布局文件:<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width= "fill_parent"    android:layout_height= "fill_parent"    android:background="#000000"    android:orientation="vertical" >    <Button        android:id= "@+id/crop_button"        android:layout_width= "match_parent"        android:layout_height= "wrap_content"        android:layout_gravity= "center"        android:layout_margin= "16dp"        android:text="CROP" />    <com.example.ima.view.ClipImageLayout        android:id= "@+id/clipImageLayout"        android:layout_width= "match_parent"        android:layout_height= "match_parent" /></LinearLayout>主要的三个View文件:import android.content.Context;import android.graphics.Bitmap;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.RelativeLayout;/** * @ClassName: ClipImageLayout * @Description: * @date 2015 -5 -10 下午10:22:24 */public class ClipImageLayout extends RelativeLayout {      private ClipZoomImageView mZoomImageView;      private ClipImageBorderView mClipImageView;      private int mHorizontalPadding = 0; // 这里测试,直接写死了大小,真正使用过程中,可以提取为自定义属性      public ClipImageLayout(Context context, AttributeSet attrs) {             super(context, attrs);             mZoomImageView = new ClipZoomImageView(context);             mClipImageView = new ClipImageBorderView(context);            android.view.ViewGroup.LayoutParams lp = new LayoutParams(                        android.view.ViewGroup.LayoutParams. MATCH_PARENT,                        android.view.ViewGroup.LayoutParams. MATCH_PARENT);             this.addView( mZoomImageView, lp);             this.addView( mClipImageView, lp);             // 计算padding的px             mHorizontalPadding = ( int) TypedValue. applyDimension(                        TypedValue. COMPLEX_UNIT_DIP, mHorizontalPadding, getResources()                                    .getDisplayMetrics());             mZoomImageView.setHorizontalPadding( mHorizontalPadding);             mClipImageView.setHorizontalPadding( mHorizontalPadding);      }      public void setImageDrawable(Drawable drawable) {             mZoomImageView.setImageDrawable(drawable);      }      public void setImageBitmap(Bitmap bitmap) {             mZoomImageView.setImageBitmap(bitmap);      }      /**       *对外公布设置边距的方法,单位为 dp       *       * @param mHorizontalPadding       */      public void setHorizontalPadding( int mHorizontalPadding) {             this. mHorizontalPadding = mHorizontalPadding;      }      /**       * 裁切图片       *       * @return       */      public Bitmap clip() {             return mZoomImageView.clip();      }}import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;public class ClipImageBorderView extends View {      /**       * 水平方向与View的边距       */      private int mHorizontalPadding;      /**       * 垂直方向与View的边距       */      private int mVerticalPadding;      /**       * 绘制的矩形的宽度       */      private int mWidth;      /**       * 边框的颜色,默认为白色       */      private int mBorderColor = Color.parseColor("#FFFFFF" );      /**       * 边框的宽度单位 dp       */      private int mBorderWidth = 1;      private Paint mPaint;      public ClipImageBorderView(Context context) {             this(context, null);      }      public ClipImageBorderView(Context context, AttributeSet attrs) {             this(context, attrs, 0);      }      public ClipImageBorderView(Context context, AttributeSet attrs, int defStyle) {             super(context, attrs, defStyle);             mBorderWidth = ( int) TypedValue. applyDimension(                        TypedValue. COMPLEX_UNIT_DIP, mBorderWidth, getResources()                                    .getDisplayMetrics());             mPaint = new Paint();             mPaint.setAntiAlias( true);      }      @Override      protected void onDraw(Canvas canvas) {             super.onDraw(canvas);             // 计算矩形区域的宽度             mWidth = getWidth() - 2 * mHorizontalPadding;             // 计算距离屏幕垂直边界 的边据             mVerticalPadding = (getHeight() - mWidth) / 2;             mPaint.setColor(Color. parseColor("#aa000000"));             mPaint.setStyle(Style. FILL);             // 绘制左边1            canvas.drawRect(0, 0, mHorizontalPadding, getHeight(), mPaint);             // 绘制右边2            canvas.drawRect(getWidth() - mHorizontalPadding, 0, getWidth(),                        getHeight(), mPaint);             // 绘制上边3            canvas.drawRect( mHorizontalPadding, 0, getWidth() - mHorizontalPadding,                         mVerticalPadding, mPaint);             // 绘制下边4            canvas.drawRect( mHorizontalPadding, getHeight() - mVerticalPadding,                        getWidth() - mHorizontalPadding, getHeight(), mPaint);             // 绘制外边框             mPaint.setColor( mBorderColor);             mPaint.setStrokeWidth( mBorderWidth);             mPaint.setStyle(Style. STROKE);            canvas.drawRect( mHorizontalPadding, mVerticalPadding, getWidth()                        - mHorizontalPadding, getHeight() - mVerticalPadding, mPaint );      }      public void setHorizontalPadding( int mHorizontalPadding) {             this. mHorizontalPadding = mHorizontalPadding;      }}import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.GestureDetector.SimpleOnGestureListener;import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.ScaleGestureDetector.OnScaleGestureListener;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewTreeObserver;import android.widget.ImageView;/** * 缩放图片的View * */public class ClipZoomImageView extends ImageView implements            OnScaleGestureListener, OnTouchListener,            ViewTreeObserver.OnGlobalLayoutListener {      public static float SCALE_MAX = 4.0f;      private static float SCALE_MID = 2.0f;      /**       * 初始化时的缩放比例,如果图片宽或高大于屏幕,此值将小于0       */      private float initScale = 1.0f;      private boolean once = true;      /**       * 用于存放矩阵的9个值       */      private final float[] matrixValues = new float[9];      /**       * 缩放的手势检测       */      private ScaleGestureDetector mScaleGestureDetector = null;      private final Matrix mScaleMatrix = new Matrix();      /**       * 用于双击检测       */      private GestureDetector mGestureDetector;      private boolean isAutoScale;      private int mTouchSlop;      private float mLastX;      private float mLastY;      private boolean isCanDrag;      private int lastPointerCount;      /**       * 水平方向与View的边距       */      private int mHorizontalPadding;      public ClipZoomImageView(Context context) {             this(context, null);      }      public ClipZoomImageView(Context context, AttributeSet attrs) {             super(context, attrs);            setScaleType(ScaleType. MATRIX);             mGestureDetector = new GestureDetector(context,                         new SimpleOnGestureListener() {                               @Override                               public boolean onDoubleTap(MotionEvent e) {                                     if ( isAutoScale == true)                                           return true;                                     float x = e.getX();                                     float y = e.getY();                                     if (getScale() < SCALE_MID) {                                          ClipZoomImageView. this.postDelayed(                                                       new AutoScaleRunnable(SCALE_MID, x, y), 16);                                           isAutoScale = true;                                    } else {                                          ClipZoomImageView. this.postDelayed(                                                       new AutoScaleRunnable(initScale, x, y), 16);                                           isAutoScale = true;                                    }                                     return true;                              }                        });             mScaleGestureDetector = new ScaleGestureDetector(context, this);             this. setOnTouchListener(this);      }      /**       * 自动缩放的任务       *       */      private class AutoScaleRunnable implements Runnable {             static final float BIGGER = 1.07f;             static final float SMALLER = 0.93f;             private float mTargetScale;             private float tmpScale;             /**             * 缩放的中心             */             private float x;             private float y;             /**             * 传入目标缩放值,根据目标值与当前值,判断应该放大还是缩小             *             * @param targetScale             */             public AutoScaleRunnable( float targetScale, float x, float y) {                   this. mTargetScale = targetScale;                   this. x = x;                   this. y = y;                   if (getScale() < mTargetScale) {                         tmpScale = BIGGER;                  } else {                         tmpScale = SMALLER;                  }            }             @Override             public void run() {                   // 进行缩放                   mScaleMatrix.postScale( tmpScale, tmpScale, x, y);                  checkBorder();                  setImageMatrix( mScaleMatrix);                   final float currentScale = getScale();                   // 如果值在合法范围内,继续缩放                   if ((( tmpScale > 1f) && (currentScale < mTargetScale))                              || (( tmpScale < 1f) && ( mTargetScale < currentScale))) {                        ClipZoomImageView. this.postDelayed( this, 16);                  } else                   // 设置为目标的缩放比例                  {                         final float deltaScale = mTargetScale / currentScale;                         mScaleMatrix.postScale(deltaScale, deltaScale, x, y);                        checkBorder();                        setImageMatrix( mScaleMatrix);                         isAutoScale = false;                  }            }      }      @Override      public boolean onScale(ScaleGestureDetector detector) {             float scale = getScale();             float scaleFactor = detector.getScaleFactor();             if (getDrawable() == null)                   return true;             /**             * 缩放的范围控制             */             if ((scale < SCALE_MAX && scaleFactor > 1.0f)                        || (scale > initScale && scaleFactor < 1.0f)) {                   /**                   * 最大值最小值判断                   */                   if (scaleFactor * scale < initScale) {                        scaleFactor = initScale / scale;                  }                   if (scaleFactor * scale > SCALE_MAX) {                        scaleFactor = SCALE_MAX / scale;                  }                   /**                   * 设置缩放比例                   */                   mScaleMatrix.postScale(scaleFactor, scaleFactor,                              detector.getFocusX(), detector.getFocusY());                  checkBorder();                  setImageMatrix( mScaleMatrix);            }             return true;      }      /**       * 根据当前图片的Matrix获得图片的范围       *       * @return       */      private RectF getMatrixRectF() {            Matrix matrix = mScaleMatrix;            RectF rect = new RectF();            Drawable d = getDrawable();             if ( null != d) {                  rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());                  matrix.mapRect(rect);            }             return rect;      }      @Override      public boolean onScaleBegin(ScaleGestureDetector detector) {             return true;      }      @Override      public void onScaleEnd(ScaleGestureDetector detector) {      }      @Override      public boolean onTouch(View v, MotionEvent event) {             if ( mGestureDetector.onTouchEvent(event))                   return true;             mScaleGestureDetector.onTouchEvent(event);             float x = 0, y = 0;             // 拿到触摸点的个数             final int pointerCount = event.getPointerCount();             // 得到多个触摸点的x与y均值             for ( int i = 0; i < pointerCount; i++) {                  x += event.getX(i);                  y += event.getY(i);            }            x = x / pointerCount;            y = y / pointerCount;             /**             * 每当触摸点发生变化时,重置mLasX , mLastY             */             if (pointerCount != lastPointerCount) {                   isCanDrag = false;                   mLastX = x;                   mLastY = y;            }             lastPointerCount = pointerCount;             switch (event.getAction()) {             case MotionEvent. ACTION_MOVE:                   float dx = x - mLastX;                   float dy = y - mLastY;                   if (! isCanDrag) {                         isCanDrag = isCanDrag(dx, dy);                  }                   if ( isCanDrag) {                         if (getDrawable() != null) {                              RectF rectF = getMatrixRectF();                               // 如果宽度小于屏幕宽度,则禁止左右移动                               if (rectF.width() <= getWidth() - mHorizontalPadding * 2) {                                    dx = 0;                              }                               // 如果高度小雨屏幕高度,则禁止上下移动                               if (rectF.height() <= getHeight() - getHVerticalPadding()                                          * 2) {                                    dy = 0;                              }                               mScaleMatrix.postTranslate(dx, dy);                              checkBorder();                              setImageMatrix( mScaleMatrix);                        }                  }                   mLastX = x;                   mLastY = y;                   break;             case MotionEvent. ACTION_UP:             case MotionEvent. ACTION_CANCEL:                   lastPointerCount = 0;                   break;            }             return true;      }      /**       * 获得当前的缩放比例       *       * @return       */      public final float getScale() {             mScaleMatrix.getValues( matrixValues);             return matrixValues[Matrix. MSCALE_X];      }      @Override      protected void onAttachedToWindow() {             super.onAttachedToWindow();            getViewTreeObserver().addOnGlobalLayoutListener( this);      }      @Override      protected void onDetachedFromWindow() {             super.onDetachedFromWindow();            getViewTreeObserver(). removeGlobalOnLayoutListener( this);      }      /**       * 垂直方向与View的边距       */      // private int getHVerticalPadding();      @Override      public void onGlobalLayout() {             if ( once) {                  Drawable d = getDrawable();                   if (d == null)                         return;                   int width = getWidth();                   int height = getHeight();                   // 拿到图片的宽和高                   int drawableW = d.getIntrinsicWidth();                   int drawableH = d.getIntrinsicHeight();                   float scale = 1.0f;                   int frameSize = getWidth() - mHorizontalPadding * 2;                   // 大图                   if (drawableW > frameSize && drawableH < frameSize) {                        scale = 1.0f * frameSize / drawableH;                  } else if (drawableH > frameSize && drawableW < frameSize) {                        scale = 1.0f * frameSize / drawableW;                  } else if (drawableW > frameSize && drawableH > frameSize) {                         float scaleW = frameSize * 1.0f / drawableW;                         float scaleH = frameSize * 1.0f / drawableH;                        scale = Math. max(scaleW, scaleH);                  }                   // 太小的图片放大处里                   if (drawableW < frameSize && drawableH > frameSize) {                        scale = 1.0f * frameSize / drawableW;                  } else if (drawableH < frameSize && drawableW > frameSize) {                        scale = 1.0f * frameSize / drawableH;                  } else if (drawableW < frameSize && drawableH < frameSize) {                         float scaleW = 1.0f * frameSize / drawableW;                         float scaleH = 1.0f * frameSize / drawableH;                        scale = Math. max(scaleW, scaleH);                  }                   initScale = scale;                   SCALE_MID = initScale * 2;                   SCALE_MAX = initScale * 4;                   mScaleMatrix.postTranslate((width - drawableW) / 2,                              (height - drawableH) / 2);                   mScaleMatrix.postScale(scale, scale, getWidth() / 2,                              getHeight() / 2);                   // 图片移动至屏幕中心                  setImageMatrix( mScaleMatrix);                   once = false;            }      }      /**       * 剪切图片,返回剪切后的bitmap对象       *       * @return       */      public Bitmap clip() {            Bitmap bitmap = Bitmap. createBitmap(getWidth(), getHeight(),                        Bitmap.Config. ARGB_8888);            Canvas canvas = new Canvas(bitmap);            draw(canvas);             return Bitmap. createBitmap(bitmap, mHorizontalPadding,                        getHVerticalPadding(), getWidth() - 2 * mHorizontalPadding,                        getWidth() - 2 * mHorizontalPadding);      }      /**       * 边界检测       */      private void checkBorder() {            RectF rect = getMatrixRectF();             float deltaX = 0;             float deltaY = 0;             int width = getWidth();             int height = getHeight();             // 如果宽或高大于屏幕,则控制范围 ; 这里的0.001是因为精度丢失会产生问题,但是误差一般很小,所以我们直接加了一个0.01             if (rect.width() + 0.01 >= width - 2 * mHorizontalPadding) {                   if (rect. left > mHorizontalPadding) {                        deltaX = -rect. left + mHorizontalPadding;                  }                   if (rect. right < width - mHorizontalPadding) {                        deltaX = width - mHorizontalPadding - rect.right;                  }            }             if (rect.height() + 0.01 >= height - 2 * getHVerticalPadding()) {                   if (rect. top > getHVerticalPadding()) {                        deltaY = -rect. top + getHVerticalPadding();                  }                   if (rect. bottom < height - getHVerticalPadding()) {                        deltaY = height - getHVerticalPadding() - rect.bottom;                  }            }             mScaleMatrix.postTranslate(deltaX, deltaY);      }      /**       * 是否是拖动行�?       *       * @param dx       * @param dy       * @return       */      private boolean isCanDrag( float dx, float dy) {             return Math. sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;      }      public void setHorizontalPadding( int mHorizontalPadding) {             this. mHorizontalPadding = mHorizontalPadding;      }      private int getHVerticalPadding() {             return (getHeight() - (getWidth() - 2 * mHorizontalPadding)) / 2;      }}

DEMO下载地址:http://download.csdn.net/detail/q908555281/9311177

0 0
原创粉丝点击