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

xiaoxiao2021-02-28  119

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

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版

转载请注明原文地址: https://www.6miu.com/read-47090.html

最新回复(0)