调用相机拍照或者从图库里选择图片裁剪后设置到界面


 
  拍照或者从相册中挑选图片设置头像是很常见的功能。同样是网上搜索了资料,知道了可以调用系统的功能实现,然后就试着开始写了。先是布局文件,就是一个ImageView和一个TextView。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">

    <ImageView  android:layout_width="200dp" android:layout_height="200dp" android:id="@+id/imageView" android:background="@mipmap/ic_launcher" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="151dp" />

    <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击修改头像" android:textSize="25sp" android:id="@+id/textView" android:layout_marginTop="108dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" />
</RelativeLayout>

MainActivity.java

package com.sy.myphoto;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.io.ByteArrayOutputStream;

public class MainActivity extends Activity {

    private ImageView iv;
    private View view;
    private RadioGroup group;
    private RadioButton rb_camera;
    private RadioButton rb_photo;

    private String SDCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();//sd卡路径

    private static final int PHOTO_REQUEST_TAKEPHOTO = 1;// 拍照
    private static final int PHOTO_REQUEST_GALLERY = 2;// 从相册中选择
    private static final int PHOTO_REQUEST_CUT = 3;// 结果
    private AlertDialog.Builder builder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//初始化控件
        initEvent();//初始化事件
        setImage();//如果有设置过头像,set上之前的头像
    }

    /** * 从SharedPreferences里读取图片名称,从缓存中读取图片,设置图片,如果没有保存过就什么也不做 */
    private void setImage() {
        SharedPreferences sp = getSharedPreferences("imageName", MODE_PRIVATE);
        String imageName = sp.getString("name", "");
        if (TextUtils.isEmpty(imageName)) {
        } else {
            byte[] p = FileUtils.readBytes(SDCardPath + "/imageCache", imageName);
           if(p!=null){
               Bitmap bitmap = BitmapFactory.decodeByteArray(p, 0, p.length);
               //设置到界面
               Drawable drawable = new BitmapDrawable(bitmap);
               iv.setBackgroundDrawable(drawable);
           }
        }
    }

    private void initEvent() {
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设置一个带items的dialog
                final String[] items = new String[]{"拍照", "相册"};
                new AlertDialog.Builder(MainActivity.this).setTitle("选择").setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub
                        switch (which) {
                            case 0:
                                // 调用系统的拍照功能
                                Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                startActivityForResult(intent1, PHOTO_REQUEST_TAKEPHOTO);
                                break;
                            case 1:
                                //调用系统图库
                                Intent intent2 = new Intent(Intent.ACTION_PICK, null);
                                intent2.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                                startActivityForResult(intent2, PHOTO_REQUEST_GALLERY);
                                break;
                        }
                    }
                }).show();
            }
        });

    }

    private void initView() {
        iv = (ImageView) findViewById(R.id.imageView);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch (requestCode) {
            case PHOTO_REQUEST_TAKEPHOTO:// 当选择拍照时调用
                if (data != null)
                    startPhotoZoom(data.getData(), 150);
                break;

            case PHOTO_REQUEST_GALLERY:// 当选择从本地获取图片时
                // 做非空判断,当我们觉得不满意想重新剪裁的时候便不会报异常
                if (data != null)
                    startPhotoZoom(data.getData(), 150);
                break;
            case PHOTO_REQUEST_CUT:// 返回的结果
                if (data != null)
                    saveAndsetPic(data);
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


    private void startPhotoZoom(Uri uri, int size) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // crop为true是设置在开启的intent中设置显示的view可以剪裁
        intent.putExtra("crop", "true");

        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);

        // outputX,outputY 是剪裁图片的宽高
        intent.putExtra("outputX", size);
        intent.putExtra("outputY", size);
        intent.putExtra("return-data", true);

        startActivityForResult(intent, PHOTO_REQUEST_CUT);
    }

    private void saveAndsetPic(Intent picdata) {
        Bundle bundle = picdata.getExtras();
        if (bundle != null) {
            Bitmap photo = bundle.getParcelable("data");
            //保存到SD卡
            String imageName = MD5Utils.md5(System.currentTimeMillis() + "");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            photo.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] p = baos.toByteArray();
            FileUtils.writeBytes(SDCardPath + "/imageCache", imageName, p);
            //将图片名字保存带本地
            SharedPreferences sp = getSharedPreferences("imageName", MODE_PRIVATE);
            sp.edit().putString("name", imageName).commit();

            //设置到界面
            Drawable drawable = new BitmapDrawable(photo);
            iv.setBackgroundDrawable(drawable);
        }
    }
}

  主要就是调用系统相册相机和裁剪的uri,然后通过 startActivityForResult,onActivityResult方法完成的。关于startActivityForResult 之前我有学过。在onActivityResult方法里根据requestCode的不同判断进行裁剪还是设置界面。在裁剪方法startPhotoZoom里,设置intent的附加参数的解释如下:
  调用相机拍照或者从图库里选择图片裁剪后设置到界面_第1张图片
  
  在saveAndsetPic方法里,除了设置界面,我把裁剪好的图片保存到本地SD卡上,然后为了方便以时间戳md5加密作为图片名字存到了SharedPreferences里。下次打开时先检查SharedPreferences里有没有存过名字,有的话就从缓存图片中读取出来设置到界面。
 

你可能感兴趣的:(android)