切换头像,拍照或者相册选择后剪裁

版权声明:转载请注明出处 https://blog.csdn.net/dl10210950/article/details/72900227

这个功能基本每个项目都会有,每次都要去翻看以前的项目,感觉不好,这里记录一下,以后需要的时候直接过来复制就行了,

1.首先是点击头像弹出一个选择框,让用户选择照相机或者打开相册

这里写图片描述

2,如果点击拍照就去调用系统照相机

case R.id.photo_take://照相的监听
                    try {
                        //调用系统照相机,注意,我这里没有适配6.0权限
                        Intent intent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        //拍照后照片的地址和命名
                        intent2.putExtra(MediaStore.EXTRA_OUTPUT,
                                Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                                "head.jpg")));
                        startActivityForResult(intent2, TAKE_PHONE);//采用ForResult打开,回调到onActivityResult
                    } catch (Exception e) {
                        Log.e("duanlian", "onClick: " + e);
                        Toast.makeText(MainActivity.this, "请允许程序获取系统照相权限", Toast.LENGTH_SHORT).show();
                    }

                    break;

3.拍照完成后会回调到onActivityResult,然后拿到图片的地址,去调用系统的剪裁功能

case TAKE_PHONE:  //照相之后回调到这里
                    //拿到照片的地址
                    File temp = new File(Environment.getExternalStorageDirectory() + "/head.jpg");
                    cropPhoto(Uri.fromFile(temp));//裁剪图片
                    break;

4,调用系统剪裁的代码

  /**
     * 调用系统的裁剪
     *
     * @param uri
     */
    public void cropPhoto(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 160);
        intent.putExtra("outputY", 160);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHONE_CROP);//剪裁完成回调到onActivityResult
    }

这里写图片描述

5,点击确定之后又回调到onActivityResult,获取到剪裁后的图片,就该干嘛就干嘛了

case PHONE_CROP://图片剪裁后回调到这里
                    if (data != null) {
                        Bundle extras = data.getExtras();
                        //拿到剪裁后的图片
                        head = extras.getParcelable("data");
                        if (head != null) {
                            setPicToView(head);//保存在SD卡中
                            ivHead.setImageBitmap(head);//用ImageView显示出来
                            //转换成字节码,上传到服务器
                            ByteArrayOutputStream output = new ByteArrayOutputStream();
                            head.compress(Bitmap.CompressFormat.JPEG, 100, output);
                            byte[] bytesOfBitmap = output.toByteArray();
                            // TODO: 2017/6/7 去上传到服务器
                        }
                    }
                    break;

6,然后就成功切换了头像

这里写图片描述

步骤大概就是这样的,调用系统相册和拍照差不多,也是获取到用户选择的图片去调用系统剪裁

完整的代码:注释比较详细,看看就懂了

package com.duanlian.changeheaddemo;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import de.hdodenhof.circleimageview.CircleImageView;

public class MainActivity extends AppCompatActivity {
    private CircleImageView ivHead;
    private ChangeHeadPopwindow mHeadPopwindow;//自定义的选择popupWindow
    private static final int PHOTO_ALBUM = 1;//调用相册的请求码
    private static final int TAKE_PHONE = 2;//照相的请求码
    private static final int PHONE_CROP = 3;//剪裁完成请求码
    //处理头像后得到的bitmap头像
    private Bitmap head;
    private static String path = "/sdcard/myHead/";//sd路径

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView() {
        ivHead = (CircleImageView) findViewById(R.id.circle_iv);
        ivHead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //调起选择框,选择从相册取还是拍照,传入上下文和点击监听
                mHeadPopwindow = new ChangeHeadPopwindow(MainActivity.this, itemsOnClick);
                mHeadPopwindow.showAtLocation(view, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
            }
        });
    }
    //为popupwindow弹出窗口实现监听类
    private View.OnClickListener itemsOnClick = new View.OnClickListener() {

        public void onClick(View v) {
            mHeadPopwindow.dismiss();//不管是点击了哪个都让弹框消失
            mHeadPopwindow.backgroundAlpha(MainActivity.this, 1f);//改变背景
            switch (v.getId()) {
                case R.id.photo_take://照相的监听
                    try {
                        //调用系统照相机,注意,我这里没有适配6.0权限
                        Intent intent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        //拍照后照片的地址和命名
                        intent2.putExtra(MediaStore.EXTRA_OUTPUT,
                                Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                                "head.jpg")));
                        startActivityForResult(intent2, TAKE_PHONE);//采用ForResult打开,回调到onActivityResult
                    } catch (Exception e) {
                        Log.e("duanlian", "onClick: " + e);
                        Toast.makeText(MainActivity.this, "请允许程序获取系统照相权限", Toast.LENGTH_SHORT).show();
                    }

                    break;
                case R.id.photo_album://相册
                    //调起系统相册
                    Intent intent1 = new Intent(Intent.ACTION_PICK, null);
                    intent1.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                    startActivityForResult(intent1, PHOTO_ALBUM);
                    break;
                default:
                    break;
            }
        }

    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode==RESULT_OK) {
            //判断请求码
            switch (requestCode) {
                case PHOTO_ALBUM://相册选择之后回调到这里
                    //取出图片后去剪裁
                    cropPhoto(data.getData());
                    break;
                case TAKE_PHONE:  //照相之后回调到这里
                    //拿到照片的地址
                    File temp = new File(Environment.getExternalStorageDirectory() + "/head.jpg");
                    cropPhoto(Uri.fromFile(temp));//裁剪图片
                    break;
                case PHONE_CROP://图片剪裁后回调到这里
                    if (data != null) {
                        Bundle extras = data.getExtras();
                        //拿到剪裁后的图片
                        head = extras.getParcelable("data");
                        if (head != null) {
                            setPicToView(head);//保存在SD卡中
                            ivHead.setImageBitmap(head);//用ImageView显示出来
                            //转换成字节码,上传到服务器
                            ByteArrayOutputStream output = new ByteArrayOutputStream();
                            head.compress(Bitmap.CompressFormat.JPEG, 100, output);
                            byte[] bytesOfBitmap = output.toByteArray();
                            // TODO: 2017/6/7 去上传到服务器
                        }
                    }
                    break;
            }
        }


        super.onActivityResult(requestCode, resultCode, data);
    }
    /**
     * 调用系统的裁剪
     *
     * @param uri
     */
    public void cropPhoto(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 160);
        intent.putExtra("outputY", 160);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHONE_CROP);//剪裁完成回调到onActivityResult
    }

    /**
     * 把bitmap写入sd卡
     * @param mBitmap
     */
    private void setPicToView(Bitmap mBitmap) {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
            return;
        }
        FileOutputStream b = null;
        File file = new File(path);
        file.mkdirs();// 创建文件夹
        //
        String fileName = path + "head.jpg";//图片名字
        Log.e("duanlian===", "setPicToView: " + fileName);
        try {
            b = new FileOutputStream(fileName);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭流
                b.flush();
                b.close();
            } catch (Exception e) {
                e.printStackTrace();

            }

        }
    }
}

看不懂把demo下载下来直接复制代码就行了
demo下载地址:点击下载

Kotlin版本下载点击下载kotlin版

猜你喜欢

转载自blog.csdn.net/dl10210950/article/details/72900227