調用相機拍照或者從圖庫裏選擇圖片裁剪後設置到界面

這裏寫圖片描述
 
  拍照或者從相冊中挑選圖片設置頭像是很常見的功能。同樣是網上搜索了資料,知道了可以調用系統的功能實現,然後就試着開始寫了。先是佈局文件,就是一個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的附加參數的解釋如下:
  這裏寫圖片描述
  
  在saveAndsetPic方法裏,除了設置界面,我把裁剪好的圖片保存到本地SD卡上,然後爲了方便以時間戳md5加密作爲圖片名字存到了SharedPreferences裏。下次打開時先檢查SharedPreferences裏有沒有存過名字,有的話就從緩存圖片中讀取出來設置到界面。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章