欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-20 09:37:43
...

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

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版

相关标签: 切换头像