一、預計實現功能:
- 從相冊選取圖片並進行剪切。
- 打開相機拍攝圖片並進行剪切。
demo地址:https://github.com/shichaohui/CropImage
二、技術使用:
- 分別使用Intent打開相機、相冊、和剪切程序。詳見代碼
- 內存卡保存相機拍攝的圖片,並在最後刪除。
三、邏輯:
- 進入圖片庫 –> 選擇圖片 –> 進入剪切程序 –> 剪切完成回到主頁。
- 進入圖片庫 –> 選擇圖片 –> 進入剪切程序 –> 未剪切直接退回到主頁。
- 進入圖片庫 –> 未選擇圖片直接退回到主頁。
- 進入相機 –> 拍照 –> 選中圖片 –> 進入剪切程序 –> 剪切完成回到主頁。
- 進入相機 –> 拍照 –> 選中圖片 –> 進入剪切程序 –> 未剪切直接退回到主頁。
- 進入相機 –> 拍照 <–> 取消圖片 –> 直接退回到主頁。
邏輯4、5、6執行完成之後都要刪除相機產生的圖片。
以下爲主要代碼:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_01"
android:layout_width="match_parent"
android:layout_height="50dip"
android:text="相冊" />
<Button
android:id="@+id/btn_02"
android:layout_width="match_parent"
android:layout_height="50dip"
android:text="拍照" />
<ImageView
android:id="@+id/imageID"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnClickListener {
private CropImage cropImage = null;
private Button btn_01 = null;
private Button btn_02 = null;
private ImageView imageView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cropImage = new CropImage(this);
btn_01 = (Button) findViewById(R.id.btn_01);
btn_02 = (Button) findViewById(R.id.btn_02);
imageView = (ImageView) findViewById(R.id.imageID);
btn_01.setOnClickListener(this);
btn_02.setOnClickListener(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap bitmap = cropImage.onResult(requestCode, resultCode, data);
if (bitmap != null) {
System.out.println(bitmap.getWidth() + "___" + bitmap.getHeight());
imageView.setImageBitmap(bitmap);
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_01:
cropImage.openAlbums();
break;
case R.id.btn_02:
cropImage.openCamera();
break;
default:
break;
}
}
}
工具類CropImage.java
import java.io.ByteArrayOutputStream;
import java.io.File;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.widget.Toast;
/**
* <p>
* 功能:
* <ul>
* <li>打開照相機拍照並剪切</li>
* <li>從相冊選擇圖片並剪切</li>
* </ul>
* 圖片剪切後的大小默認130*130像素<br>
* 請在使用本類實例的Activity的onActivityResult方法中調用本類實例的onResult方法,以獲取剪切後的Bitmap實例
* </p>
*
* @author [email protected]
*
*/
public class CropImage {
private Context context = null;
private static final int FLAG_CAMERA = 1; // 打開相機
private static final int FLAG_ALBUMS = 2; // 打卡圖片庫
private static final int FLAG_CROP = 3; // 執行剪切
private static final String IMAGE_UNSPECIFIED = "image/*"; // 圖片的MIME類型
private String filePath = ""; // 照相時圖片的保存路徑
private String fileName = "/temp.jpg"; // 照相時圖片的保存名字
private int aspectX = 1; // 剪切後的圖片寬度高度比例
private int aspectY = 1;
private int outputX = 130; // 剪切後的圖片寬度
private int outputY = 130; // 剪切後的圖片高度
public CropImage(Context context) {
this.context = context;
}
/** 打開相冊,選擇圖片後執行剪切 */
public void openAlbums() {
// 打開圖片庫
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
((Activity) context).startActivityForResult(intent, FLAG_ALBUMS);
}
/** 打開相機,拍照後執行剪切 */
public void openCamera() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
filePath = Environment.getExternalStorageDirectory().getPath()
+ fileName;
// 打開照相機
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 設置相片保存路徑
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(filePath)));
((Activity) context).startActivityForResult(intent, FLAG_CAMERA);
} else {
Toast.makeText(context, "存儲卡不可用,請從相冊選取", Toast.LENGTH_SHORT).show();
}
}
/**
* Activity的onActivityResult方法中調用此方法,
* 返回已個裁剪好的Bitmap實例,此方法會返回null值,請注意null值判斷
*
* @param requestCode
* @param resultCode
* @param data
* @return
*/
public Bitmap onResult(int requestCode, int resultCode, Intent data) {
File file = new File(filePath);
if (requestCode == FLAG_CAMERA) {
/* resultCode == -1說明選定了圖片,否則就是沒有選定圖片直接退出了相機 */
if (resultCode == -1) {
startPhotoZoom(Uri.fromFile(file));
} else if (file.exists()) {
file.delete(); // 刪除臨時的圖片文件
}
} else if (requestCode == FLAG_ALBUMS) {
if (data == null) {
return null;
}
Uri uri = data.getData();
if (uri != null)
startPhotoZoom(uri);
} else if (requestCode == FLAG_CROP) {
if (file.exists())
file.delete(); // 刪除臨時的圖片文件
return getBitmapFromIntent(data);
}
return null;
}
/**
* 從Intent中解析出一個Bitmap實例
*
* @param data
* 數據源
* @return
*/
private Bitmap getBitmapFromIntent(Intent data) {
if (data == null) {
return null;
}
Bitmap photo = null;
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// 壓縮文件
photo.compress(CompressFormat.JPEG, 75, stream);
}
return photo;
}
/**
* 調用系統剪切程序剪切圖片
*
* @param uri
* 圖片的Uri
*/
private void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
intent.putExtra("crop", "true");
// aspectX aspectY 是寬高的比例
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
// outputX outputY 是裁剪圖片寬高
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("return-data", true);
((Activity) context).startActivityForResult(intent, FLAG_CROP);
}
}
對於使用拍照功能產生的圖片,最後需要刪除,所以需要加入以下權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />