拍照/從相冊讀取圖片后進行裁剪的方法


本范例實現的是用戶可以通過拍照、相冊獲取圖片,然后進行裁剪,最后將結果保存在IamgeView中。當然你可以選擇將結果同時存放在sd卡中,作為以后的緩存。

思路:

1.通過拍照獲取圖片

進入系統自帶的相機界面——>拍照——>保存在sd卡中——>讀取sd卡的文件進行裁減。PS:裁剪前先判斷是否獲取到圖片了

2.通過系統相冊獲取圖片

進入系統相冊——>找到圖片——>進行裁減。PS:裁剪前線判斷是否獲取到系統的圖片了

 

接下來貼上實現方法:

1.進入拍照界面或者相冊的方法,獲取信息后回調onActivityResult()方法

public void buttonListener(View v) {
        switch (v.getId()) {
        case R.id.fromAlbum_button:
            // 來自相冊
            Intent albumIntent = new Intent(Intent.ACTION_PICK, null);
            /**
             * 下面這句話,與其它方式寫是一樣的效果,如果:
             * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
             * intent.setType(""image/*");設置數據類型
             * 要限制上傳到服務器的圖片類型時可以直接寫如:"image/jpeg 、 image/png等的類型"
             */
            albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            startActivityForResult(albumIntent, ALBUM_OK);
            break;
        case R.id.fromCamera_button:
            // 來自相機
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 下面這句指定調用相機拍照后的照片存儲的路徑
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判斷返回結果的標識
            break;

        default:
            break;
        }
    }

 

2.得到信息,交給onActivityResult()處理。先判斷是否得到信息,如果得到就進行裁剪。

在這里需要注意的是從相冊返回的結果存到的是data里面,拍照后的圖片結果存放的是file文件。由於從相冊取到的圖片可能很大,所以系統會經過一定的壓縮,data得到的圖片有可能失真。具體問題有待實際解決。而拍照后的圖片來源是文件,所以應該不會有什么問題。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("requestCode = " + requestCode);
        switch (requestCode) {
        // 如果是直接從相冊獲取
        case ALBUM_OK:
            //從相冊中獲取到圖片了,才執行裁剪動作
            if (data != null) {
                clipPhoto(data.getData());
            }
            break;
        // 如果是調用相機拍照時
        case CAMERA_OK:
            // 當拍照到照片時進行裁減,否則不執行操作
            if (file.exists()) {
                clipPhoto(Uri.fromFile(file));//開始裁減圖片
            }
            break;
        // 取得裁剪后的圖片,這里將其設置到imageview中
        case CUT_OK:
            /**
             * 非空判斷大家一定要驗證,如果不驗證的話, 在剪裁之后如果發現不滿意,
             * 要重新裁剪,丟棄 當前功能時,會報NullException
             */
            if (data != null) {
                setPicToView(data);
            }
            break;
        default:
            break;

        }
        super.onActivityResult(requestCode, resultCode, data);
    }

 

3.進行圖片裁剪的方法:

如果在裁剪時返回的圖片很大,系統會強行進行裁剪。

/**
     * 裁剪圖片方法實現
     * @param uri
     */
    public void clipPhoto(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // 下面這個crop = true是設置在開啟的Intent中設置顯示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是寬高的比例,這里設置的是正方形(長寬比為1:1)
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪圖片寬高
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CUT_OK);
    }

 

4.將裁剪好的圖片設置到ImageView中,同時清除緩存圖片

/**
     * 保存裁剪之后的圖片數據 將圖片設置到imageview中
     * 
     * @param picdata
     */
    private void setPicToView(Intent picdata) {
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            Drawable drawable = new BitmapDrawable(photo);
            showIv.setImageDrawable(drawable);
            file.delete();//設置成功后清除之前的照片文件
        }
    }

 

最后貼上全部的代碼:

package com.kale.picturecut;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
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.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {

    // 拍照成功,讀取相冊成功,裁減成功
    private final int  ALBUM_OK = 1, CAMERA_OK = 2,CUT_OK = 3;
    private ImageView showIv;
    private File file;

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

        // 定義拍照后存放圖片的文件位置和名稱,使用完畢后可以方便刪除
        file = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
        file.delete();// 清空之前的文件

        showIv = (ImageView) findViewById(R.id.show_imageView);
    }

    public void buttonListener(View v) {
        switch (v.getId()) {
        case R.id.fromAlbum_button:
            // 來自相冊
            Intent albumIntent = new Intent(Intent.ACTION_PICK, null);
            /**
             * 下面這句話,與其它方式寫是一樣的效果,如果:
             * intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
             * intent.setType(""image/*");設置數據類型
             * 要限制上傳到服務器的圖片類型時可以直接寫如:"image/jpeg 、 image/png等的類型"
             */
            albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            startActivityForResult(albumIntent, ALBUM_OK);
            break;
        case R.id.fromCamera_button:
            // 來自相機
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 下面這句指定調用相機拍照后的照片存儲的路徑
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            startActivityForResult(cameraIntent, CAMERA_OK);// CAMERA_OK是用作判斷返回結果的標識
            break;

        default:
            break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("requestCode = " + requestCode);
        switch (requestCode) {
        // 如果是直接從相冊獲取
        case ALBUM_OK:
            //從相冊中獲取到圖片了,才執行裁剪動作
            if (data != null) {
                clipPhoto(data.getData());
            }
            break;
        // 如果是調用相機拍照時
        case CAMERA_OK:
            // 當拍照到照片時進行裁減,否則不執行操作
            if (file.exists()) {
                clipPhoto(Uri.fromFile(file));//開始裁減圖片
            }
            break;
        // 取得裁剪后的圖片,這里將其設置到imageview中
        case CUT_OK:
            /**
             * 非空判斷大家一定要驗證,如果不驗證的話, 在剪裁之后如果發現不滿意,
             * 要重新裁剪,丟棄 當前功能時,會報NullException
             */
            if (data != null) {
                setPicToView(data);
            }
            break;
        default:
            break;

        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 裁剪圖片方法實現
     * @param uri
     */
    public void clipPhoto(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // 下面這個crop = true是設置在開啟的Intent中設置顯示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是寬高的比例,這里設置的是正方形(長寬比為1:1)
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪圖片寬高
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CUT_OK);
    }

    /**
     * 保存裁剪之后的圖片數據 將圖片設置到imageview中
     * 
     * @param picdata
     */
    private void setPicToView(Intent picdata) {
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            Drawable drawable = new BitmapDrawable(photo);
            showIv.setImageDrawable(drawable);
            file.delete();//設置成功后清除之前的照片文件
        }
    }
}

 

權限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.per

 

源碼下載:http://download.csdn.net/detail/shark0017/7964819

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM