博客
关于我
android 头像选择,裁剪全套解决方案,你值得拥有!
阅读量:363 次
发布时间:2019-03-05

本文共 28036 字,大约阅读时间需要 93 分钟。

头像选取,裁切,上传等功能基本上是现在每个app必备的功能,实现起来倒是不复杂,确是要花点时间。恰好前几天把这个功能做完了,本着不重复造轮子的原则,提供一整套解决方案,希望给能用到的小伙伴。

首先放头像必须得有一个控件,我这里用的 CircleImageView

implementation 'de.hdodenhof:circleimageview:2.1.0'

然后是点击控件弹出选择框拍照或者是去图库选取,如图

其中底部的控件用的是第三方控件,具体可以访问我的github主页查看:

示例代码:

//头像控件点击事件logo.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ActionSheetDialog actionSheetDialog = new ActionSheetDialog(                        mContext).builder().setCancelable(false)                        .setCanceledOnTouchOutside(true);                for (int i = 0; i < fileFrom.length; i++) {                    actionSheetDialog.addSheetItem(fileFrom[i],                            ActionSheetDialog.SheetItemColor.Blue,                            new ActionSheetDialog.OnSheetItemClickListener() {                                @Override                                public void onClick(int which) {                                    getFile(which);                                }                            });                }                actionSheetDialog.show();            }});//处理点击事件private void getFile(int index) {        switch (index) {            case 1:                takePic();                break;            case 2:                gallery();                break;        }    }    //去图库选择    private void gallery() {        PictureSelector.create(this)                .openGallery(PictureMimeType.ofImage())// 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()                .theme(themeId)// 主题样式设置 具体参考 values/styles   用法:R.style.picture.white.style                .maxSelectNum(1)// 最大图片选择数量                .minSelectNum(1)// 最小选择数量                .isCamera(false)// 是否显示拍照按钮                .imageSpanCount(5)// 每行显示个数                .compress(false)// 是否压缩 true or false                .maxSelectNum(1)// 最大图片选择数量                .isZoomAnim(true)// 图片列表点击 缩放效果 默认true                .synOrAsy(true)//同步true或异步false 压缩 默认同步                .glideOverride(120, 120)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度                //.selectionMedia(picList)// 是否传入已选图片                .minimumCompressSize(100)// 小于100kb的图片不压缩                .forResult(Pic_OK);//结果回调onActivityResult code    }    //拍照    private void takePic() {        //单独拍照        PictureSelector.create(this)                .openCamera(PictureMimeType.ofImage())                .theme(themeId)// 主题样式设置 具体参考 values/styles                .minSelectNum(1)// 最小选择数量                .compress(false)                .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选                .isCamera(false)// 是否显示拍照按钮                .glideOverride(120, 120)// glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度                //.selectionMedia(picList)// 是否传入已选图片                .imageSpanCount(5)// 每行显示个数                .maxSelectNum(1)// 最大图片选择数量                .isZoomAnim(true)// 图片列表点击 缩放效果 默认true                .synOrAsy(true)//同步true或异步false 压缩 默认同步                .minimumCompressSize(100)// 小于100kb的图片不压缩                .forResult(Camea_OK);    }

其中拍照和图库选择图片需要用到第三方框架:

implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.1.9'

选取完成图片或者拍照完成之后,根据传入的result值回调到onActivityResult方法

@Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        LogUtils.e("requestCode : "+requestCode);        switch (requestCode) {            case Camea_OK:                // 图片选择结果回调                List<LocalMedia> resultCamera = PictureSelector.obtainMultipleResult(data);                if(resultCamera != null && resultCamera.size() > 0){                    Intent cameraIntent = new Intent(mContext, ClipImageActivity.class);                    cameraIntent.putExtra("path",resultCamera.get(0).getPath());                    startActivityForResult(cameraIntent,CLIP);                }                break;            case Pic_OK:                // 图片选择结果回调                List<LocalMedia> resultGallery = PictureSelector.obtainMultipleResult(data);                if(resultGallery != null && resultGallery.size() > 0){                    Intent picIntent = new Intent(mContext, ClipImageActivity.class);                    picIntent.putExtra("path",resultGallery.get(0).getPath());                    startActivityForResult(picIntent,CLIP);                }                break;            case CLIP:                if(data != null){                    String path = data.getStringExtra("result_path");                    LogUtils.e("path : "+path);                    uploadHead(path);                }                break;        }    }

onActivityResult方法中主要是获取了图片的地址,然后通过path这个参数传入到裁剪页面,裁剪页面效果图:

裁剪页面主要是用了一个自定义的view,分别包含一个能缩放的ImageView,还有一个圆形遮罩,代码如下:

自定义view:ClipImageLayout

public class ClipImageLayout extends RelativeLayout {	private ClipZoomImageView mZoomImageView;	private CutImageBorderView mClipImageView;	private int mHorizontalPadding = 20;// 框左右的边距,这里左右边距为0,为�?��屏幕宽度的正方形�?	public ClipImageLayout(Context context, AttributeSet attrs) {		super(context, attrs);		mZoomImageView = new ClipZoomImageView(context);		mClipImageView = new CutImageBorderView(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();	}}

缩放的imageView:ClipZoomImageView

public class ClipZoomImageView extends AppCompatImageView implements ScaleGestureDetector.OnScaleGestureListener,        View.OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener {    public static float SCALE_MAX = 4.0f;    private static float SCALE_MID = 2.0f;    /**     * 初始化时的缩放比例,如果图片宽或高大于屏幕,此�?将小�?     */    private float initScale = 1.0f;    private boolean once = true;    /**     * 用于存放矩阵�?个�?     */    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 GestureDetector.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;            // 垂直方向的边�?            // getHVerticalPadding() = (getHeight() - (getWidth() - 2 *            // mHorizontalPadding)) / 2;            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);        //将剪裁的图片压缩到500k以下,如果没需求就注释该段代码        ByteArrayOutputStream baos = new ByteArrayOutputStream();        int options = 100;//保存的图片自动压缩低于500k        bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);        while (baos.toByteArray().length / 1024 > 500) {            baos.reset();            options -= 10;            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);        }        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();        // 如果宽或高大于屏幕,则控制范�?; 这里�?.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;    }}

圆形遮罩:CutImageBorderView

public class CutImageBorderView 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 CutImageBorderView(Context context)    {        this(context, null);    }    public CutImageBorderView(Context context, AttributeSet attrs)    {        this(context, attrs, 0);    }    public CutImageBorderView(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(Paint.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);        RectF rect = new RectF(mHorizontalPadding, mVerticalPadding, getWidth()                - mHorizontalPadding, getHeight() - mVerticalPadding);        Path mPath = new Path();        mPath.moveTo(mHorizontalPadding,mVerticalPadding);        mPath.lineTo(mHorizontalPadding,getHeight()/2);        mPath.arcTo(rect,180,90);        mPath.lineTo(mHorizontalPadding,mVerticalPadding);        canvas.drawPath(mPath,mPaint);        mPath.reset();        mPath.moveTo(getWidth() - mHorizontalPadding,mVerticalPadding);        mPath.lineTo(getWidth()/2,mVerticalPadding);        mPath.arcTo(rect,270,90);        mPath.lineTo(getWidth() - mHorizontalPadding,mVerticalPadding);        canvas.drawPath(mPath,mPaint);        mPath.reset();        mPath.moveTo(getWidth() - mHorizontalPadding,getHeight() - mVerticalPadding);        mPath.lineTo(getWidth() - mHorizontalPadding,getHeight()/2);        mPath.arcTo(rect,0,90);        mPath.lineTo(getWidth() - mHorizontalPadding,getHeight() - mVerticalPadding);        canvas.drawPath(mPath,mPaint);        mPath.reset();        mPath.moveTo(mHorizontalPadding,getHeight() - mVerticalPadding);        mPath.lineTo(getWidth()/2,getHeight()-mVerticalPadding);        mPath.arcTo(rect,90,90);        mPath.lineTo(mHorizontalPadding,getHeight() - mVerticalPadding);        canvas.drawPath(mPath,mPaint);        // 绘制外边框        mPaint.setColor(mBorderColor);        mPaint.setStrokeWidth(mBorderWidth);        mPaint.setStyle(Paint.Style.STROKE);        canvas.drawCircle(getWidth()/2,getHeight()/2 ,getWidth()/2 - mHorizontalPadding,mPaint);    }    public void setHorizontalPadding(int mHorizontalPadding)    {        this.mHorizontalPadding = mHorizontalPadding;    }}

最终在裁剪页面使用代码示例:

public class ClipImageActivity extends BaseActivity {    @BindView(R.id.back)    ImageView back;    @BindView(R.id.title)    TextView title;    @BindView(R.id.right_btn)    TextView right_btn;    @BindView(R.id.clipImageLayout)    ClipImageLayout clipImageLayout;    private String path;    @Override    protected int getContentViewId() {        return R.layout.activity_clip_image;    }    @Override    protected void initBundleData() {        path = getIntent().getStringExtra("path");    }    @Override    protected void initView() {        title.setText("头像选取");        right_btn.setVisibility(View.VISIBLE);        right_btn.setText("确定");        // 有的系统返回的图片是旋转了,有的没有旋转,所以处理        int degreee = readBitmapDegree(path);        Bitmap bitmap = createBitmap(path);        if (bitmap != null) {            if (degreee == 0) {                clipImageLayout.setImageBitmap(bitmap);            } else {                clipImageLayout.setImageBitmap(rotateBitmap(degreee, bitmap));            }        } else {            finish();        }    }    @Override    protected void initData() {    }    @Override    protected void initEvent() {        back.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                finish();            }        });        right_btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                String path = FileUtils.saveBitmapFile(clipImageLayout.clip(),"head");                Intent intent = new Intent();                intent.putExtra("result_path",path);                setResult(1,intent);                finish();            }        });    }    private Bitmap createBitmap(String path) {        if (path == null) {            return null;        }        BitmapFactory.Options opts = new BitmapFactory.Options();        //不在内存中读取图片的宽高        opts.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, opts);        int width = opts.outWidth;        opts.inSampleSize = width > 1080 ? (int)(width / 1080) : 1 ;//注意此处为了解决1080p手机拍摄图片过大所以做了一定压缩,否则bitmap会不显示        opts.inJustDecodeBounds = false;// 这里一定要将其设置回false,因为之前我们将其设置成了true        opts.inPurgeable = true;        opts.inInputShareable = true;        opts.inDither = false;        opts.inPurgeable = true;        FileInputStream is = null;        Bitmap bitmap = null;        try {            is = new FileInputStream(path);            bitmap = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (is != null) {                    is.close();                    is = null;                }            } catch (IOException e) {                e.printStackTrace();            }        }        return bitmap;    }    // 读取图像的旋转度    private int readBitmapDegree(String path) {        int degree = 0;        try {            ExifInterface exifInterface = new ExifInterface(path);            int orientation = exifInterface.getAttributeInt(                    ExifInterface.TAG_ORIENTATION,                    ExifInterface.ORIENTATION_NORMAL);            switch (orientation) {                case ExifInterface.ORIENTATION_ROTATE_90:                    degree = 90;                    break;                case ExifInterface.ORIENTATION_ROTATE_180:                    degree = 180;                    break;                case ExifInterface.ORIENTATION_ROTATE_270:                    degree = 270;                    break;            }        } catch (IOException e) {            e.printStackTrace();        }        return degree;    }    // 旋转图片    private Bitmap rotateBitmap(int angle, Bitmap bitmap) {        // 旋转图片 动作        Matrix matrix = new Matrix();        matrix.postRotate(angle);        // 创建新的图片        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,                bitmap.getWidth(), bitmap.getHeight(), matrix, false);        return resizedBitmap;    }}

先通过path获取到原图,然后把原图设置到缩放imageview中,等确定好需要裁剪的返回,获取裁剪的图片,通过setresult返回。然后在前一个页面的onActivityResult进行处理,可以参考前面贴出的request code为CLIP的代码段,最终获取到裁剪的头像上传即可。

当然如果你想用矩形的裁剪框,可以将CutImageBorderView替换成下面的这个即可

public class ClipImageBorderView extends View {	/**	 * 水平方向与View的边距	 */	private int mHorizontalPadding;	/**	 * 垂直方向与View的边距	 */	private int mVerticalPadding;	/**	 * 绘制的矩形的宽度	 */	private int mWidth;	/**	 * 边框的颜色,默认为白色	 */	private int mBorderColor = Color.parseColor("#4D4D4D");	/**	 * 边框的宽度单位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;	}}

好了, 到这里,一整套头像上传的处理方案就可以拿来即用了,直接copy代码即可。

你可能感兴趣的文章
11.2.6 时间值的小数秒
查看>>
11.2.7 日期和时间类型之间的转换
查看>>
附录 B 错误信息和常见问题
查看>>
redis 内存溢出_从数据存储的角度告诉你Redis为什么这么快!
查看>>
实例分析Facebook激励视频广告接入
查看>>
实例:使用OKGO下载网络压缩包资源,然后解压缩放在本地使用
查看>>
Android主题和样式精炼详解
查看>>
HDFS Missing Block诊断信息的改进
查看>>
解决mybatis嵌套查询使用PageHelper分页不准确
查看>>
Redis源码分析(七)--- zipmap压缩图
查看>>
大规模集群自动化部署工具--Chef的安装部署
查看>>
一致性哈希算法
查看>>
HDFS源码分析(六)-----租约
查看>>
自定义Hive Sql Job分析工具
查看>>
聊聊HDFS RBF第二阶段的主要改进
查看>>
公司如何使用开源软件
查看>>
【MySQL】(九)触发器
查看>>
关于Altium Designer 09导出BOM表不能正确分类问题
查看>>
Oracle 11G环境配置
查看>>
【Spark】(六)Spark 运行流程
查看>>