Android 上传头像自定义(剪切、平移,缩放)

点击进入下载源码
今天是愚人节,但是我发表的内容可不是用来愚人的。上传图片时很多应用的硬需求,我们的应用也不例外。以前上传头像时感觉是那样的so-easy,但是前几天的上传图片让我很是头疼。原本的上传头像代码直接搬过来使用时发现在三星手机上面不能使用,于是就大改特该,改过之后终于可以使用了,没想到在华为手机上面又不能使用了,仔细debug一下看个究竟原来是Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)的设置问题,三星的Action和华为的还有小米的是不一样的,怎么办呢?于是就想到了获取手机的机型根据机型进行拍照上传。但是更头疼的事情还在后面呢,由于调用的是系统的拍照剪切,没想到三星的手机系统默认的是旋转90度,真是TMD让我伤心啊,于是就用根据旋转的角度方法进行旋转,方法如下:

public Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    private int readPictureDegree(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;
    }

没想到的是读取旋转的角度却是0,当然是旋转不过来了,实在是没有办法了就看看微信是怎么整的,原来微信是自定义的剪切图片,在拍照后不调用系统的剪切功能,而是直接在拍照后使用自定义的裁剪方法,因为拍照时的旋转角度还是可以获取到的,然后根据旋转的角度进行逆向旋转回来。于是自己就进行了自定义裁剪的代码实现拍照裁剪。同时解决的过程中也解决了一些机型的不兼容,只是本次实现的拍照上传裁剪和选择相册裁剪在三星(S6)、华为、小米、魅族手机上面是没有问题的。
以下是实现裁剪平移缩放效果的代码如下

public class CutView extends View {
    private Paint paint = new Paint();
    private Paint borderPaint = new Paint();

    /** 自定义顶部栏高度,如不是自定义,则默认为0即可 */
    private int customTopBarHeight = 0;
    /** 裁剪框长宽比,默认4:3 */
    private double clipRatio = 0.75;
    /** 裁剪框宽度 */
    private int clipWidth = -1;
    /** 裁剪框高度 */
    private int clipHeight = -1;
    /** 裁剪框左边空留宽度 */
    private int clipLeftMargin = 0;
    /** 裁剪框上边空留宽度 */
    private int clipTopMargin = 0;
    /** 裁剪框边框宽度 */
    private int clipBorderWidth = 1;
    private boolean isSetMargin = false;
    private OnDrawListenerComplete listenerComplete;

    public CutView(Context context) {
        super(context);
    }

    public CutView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CutView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = this.getWidth();
        int height = this.getHeight();
        // 如没有显示设置裁剪框高度和宽度,取默认值
        if (clipWidth == -1 || clipHeight == -1) {
            clipWidth = width - 50;
            clipHeight = (int) (clipWidth * clipRatio);
            // 横屏
            if (width > height) {
                clipHeight = height - 50;
                clipWidth = (int) (clipHeight / clipRatio);
            }
        }
        // 如没有显示设置裁剪框左和上预留宽度,取默认值
        if (!isSetMargin) {
            clipLeftMargin = (width - clipWidth) / 2;
            clipTopMargin = (height - clipHeight) / 2;
        }
        // 画阴影
        paint.setAlpha(100);
        // top
        canvas.drawRect(0, customTopBarHeight, width, clipTopMargin, paint);
        // left
        canvas.drawRect(0, clipTopMargin, clipLeftMargin, clipTopMargin
                + clipHeight, paint);
        // right
        canvas.drawRect(clipLeftMargin + clipWidth, clipTopMargin, width,
                clipTopMargin + clipHeight, paint);
        // bottom
        canvas.drawRect(0, clipTopMargin + clipHeight, width, height, paint);

        // 画边框
        borderPaint.setStyle(Style.STROKE);
        borderPaint.setColor(Color.WHITE);
        borderPaint.setStrokeWidth(clipBorderWidth);
        canvas.drawRect(clipLeftMargin, clipTopMargin, clipLeftMargin
                + clipWidth, clipTopMargin + clipHeight, borderPaint);

        if (listenerComplete != null) {
            listenerComplete.onDrawCompelete();
        }
    }

    public int getCustomTopBarHeight() {
        return customTopBarHeight;
    }

    public void setCustomTopBarHeight(int customTopBarHeight) {
        this.customTopBarHeight = customTopBarHeight;
    }

    public double getClipRatio() {
        return clipRatio;
    }

    public void setClipRatio(double clipRatio) {
        this.clipRatio = clipRatio;
    }

    public int getClipWidth() {
        // 减clipBorderWidth原因:截图时去除边框白线
        return clipWidth - clipBorderWidth;
    }

    public void setClipWidth(int clipWidth) {
        this.clipWidth = clipWidth;
    }

    public int getClipHeight() {
        return clipHeight - clipBorderWidth;
    }

    public void setClipHeight(int clipHeight) {
        this.clipHeight = clipHeight;
    }

    public int getClipLeftMargin() {
        return clipLeftMargin + clipBorderWidth;
    }

    public void setClipLeftMargin(int clipLeftMargin) {
        this.clipLeftMargin = clipLeftMargin;
        isSetMargin = true;
    }

    public int getClipTopMargin() {
        return clipTopMargin + clipBorderWidth;
    }

    public void setClipTopMargin(int clipTopMargin) {
        this.clipTopMargin = clipTopMargin;
        isSetMargin = true;
    }

    public void addOnDrawCompleteListener(OnDrawListenerComplete listener) {
        this.listenerComplete = listener;
    }

    public void removeOnDrawCompleteListener() {
        this.listenerComplete = null;
    }

    /**
     * 裁剪区域画完时调用接口
     * 
     * @author Cow
     * 
     */
    public interface OnDrawListenerComplete {
        public void onDrawCompelete();
    }

}

下面是实现拍照和选择相册的代码

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == FLAG_CHOOSE_IMG && resultCode == RESULT_OK) {
            if (data != null) {
                Uri uri = data.getData();
                if (!TextUtils.isEmpty(uri.getAuthority())) {
                    Cursor cursor = getContentResolver().query(uri,
                            new String[] { MediaStore.Images.Media.DATA },
                            null, null, null);
                    if (null == cursor) {
                        Toast.makeText(getApplicationContext(), "图片没找到", 0)
                                .show();
                        return;
                    }
                    cursor.moveToFirst();
                    String path = cursor.getString(cursor
                            .getColumnIndex(MediaStore.Images.Media.DATA));
                    cursor.close();

                    Intent intent = new Intent(this, CutPictureAty.class);
                    intent.putExtra("path", path);
                    startActivityForResult(intent, FLAG_MODIFY_FINISH);
                } else {
                    Intent intent = new Intent(this, CutPictureAty.class);
                    intent.putExtra("path", uri.getPath());
                    startActivityForResult(intent, FLAG_MODIFY_FINISH);
                }
            }
        } else if (requestCode == FLAG_MODIFY_FINISH && resultCode == RESULT_OK) {
            if (data != null) {
                final String path = data.getStringExtra("path");
                Bitmap b = BitmapFactory.decodeFile(path);
                img_pic.setImageBitmap(b);
            }
        }
        switch (requestCode) {
        case CAMERA_WITH_DATA:
            // 照相机程序返回的,再次调用图片剪辑程序去修剪图片
            startCropImageActivity(Environment.getExternalStorageDirectory()
                    + "/" + TMP_PATH);
            break;
        }
    }

    // 裁剪图片的Activity
    private void startCropImageActivity(String path) {
        Intent intent = new Intent(this, CutPictureAty.class);
        intent.putExtra("path", path);
        startActivityForResult(intent, FLAG_MODIFY_FINISH);
    }

    private void startAlbum() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, FLAG_CHOOSE_IMG);
    }

实现效果图
拍照裁剪效果图
拍照裁剪
相册裁剪效果图

平移缩放效果图

如有疑问欢迎加群Android技术交流群 50208422或Android交流群 470707794,探讨技术,欢迎加入。
点击进入下载源码

Github下载地址

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值