调用系统相册获取图片(大图片可以选择裁剪),系统相机拍照保存并裁剪:
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
/**
* 调用相机拍照 及 裁剪图片
*/
public class PhotoUtils {
/** 拍照 */
public int TAKE_PHOTO=0;
/** 相册*/
public int PHOTO_ALBUM=1;
/** 图片大小 1M*/
private int bitmapsize=3*1024*1024;
/** 获取到bitmap的uri*/
private Uri bitmapuri;
private Bitmap bitmap;
private static Activity activity;
private static PhotoUtils instance;
/**
* 初始化
* @param activity
* @return
*/
public static PhotoUtils Initialize(Activity activity){
if(instance==null)
instance=new PhotoUtils();
PhotoUtils.activity=activity;
return instance;
}
public interface ProblemCallback{
/**
* 用户提示
* @param text
*/
void Hint(String text);
/**
* 成功获取图片
* @param bitmap
*/
void GetBitmapSuccess(Bitmap bitmap);
}
/**
* 清除
*/
public void ClearBitmap(){
activity=null;
if(bitmap!=null){
bitmap.recycle();
bitmap=null;
}
}
/**
* 打开系统相机
* @param tag 标识符
* @return
*/
public boolean OpenCamera(int tag){
TAKE_PHOTO=tag;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
activity.startActivityForResult(intent, tag);
return true;
}
/**
* 打开系统相册
* @param tag 标识符
* @return success if return true
*/
public boolean OpenPhotoAlbum(int tag){
PHOTO_ALBUM=tag;
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
activity.startActivityForResult(intent, tag);
return true;
}
/**
* 调用相册选中图片并裁剪
* @param requestCode
*/
public void ClipBitmapfromphotoalbum(int requestCode){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
activity.startActivityForResult(intent, requestCode);
}
/**
* 选取图片后再裁剪
* @param outputX
* @param outputY
* @param requestCode
*/
public void ClipBitmapWithCamera(int outputX, int outputY, int requestCode){
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(bitmapuri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
intent.putExtra("scale", true);
activity.startActivityForResult(intent, requestCode);
}
/**
* 处理调用 相册/相机之后获取的图片
* @param data 打开相机返回的intent
* @param tag 标识符
* @param filename 需要保存图片的文件夹名(默认保存在跟目录下)
* @param photoname 命名图片
* @param callback ProblemCallback 接口
*/
public void DealWithUsualData(Intent data,int tag,String filename,String photoname,ProblemCallback callback){
if(callback==null)
return;
if(data==null)
callback.Hint("打开系统设备失败");
if(TAKE_PHOTO==tag){
bitmap=(Bitmap) data.getExtras().get("data");
if(bitmap!=null){
if(saveBitmap(bitmap,filename,photoname,callback)){
try {
callback.GetBitmapSuccess(getThumbnail(activity,bitmapuri, 500));
} catch (FileNotFoundException e) {
callback.Hint("没有找到文件夹");
} catch (IOException e) {
callback.Hint("抱歉!选取照片出错,请重新选择");
}
};
}else {
callback.Hint("获取图片失败");
}
}else if(PHOTO_ALBUM==tag){
bitmapuri=data.getData();
try {
callback.GetBitmapSuccess(getThumbnail(activity,bitmapuri, 500));
} catch (FileNotFoundException e) {
callback.Hint("没有找到文件夹");
} catch (IOException e) {
callback.Hint("抱歉!选取照片出错,请重新选择");
}
}else{
callback.Hint("发现未知错误,请稍候重试!");
}
}
/**
* 处理裁剪后的图片
* @param data
* @param callback
*/
public void DealWithClipData(Intent data,ProblemCallback callback){
bitmap=(Bitmap) data.getExtras().get("data");
if(getBitmapSize(bitmap)>bitmapsize){
compressImage(bitmap);
callback.GetBitmapSuccess(bitmap);
}else{
LogUtils.i("不压缩压缩"+getBitmapSize(bitmap));
callback.GetBitmapSuccess(bitmap);
}
}
/**
* 保存照片
* @param bitmap
* @param filename
* @param photoname
* @param callback
*/
private boolean saveBitmap(Bitmap bitmap, String filename, String photoname, ProblemCallback callback) {
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
callback.Hint("没有检测到sd卡,无法保存图片");
return false;
}
if(filename==null||filename.equals("")){
filename=photoname;
}
if(photoname==null||photoname.equals("")){
photoname="unknown";
}
String path=GetExternalStorageDirectory()+"/"+filename;
File file=new File(path);
if(!file.exists()){
file.mkdirs();
}
String savePictrueFileName=getStringToday()+photoname;
File savephotofile=new File(path, savePictrueFileName);
bitmapuri=Uri.fromFile(savephotofile);
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savephotofile, false));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
} catch (Exception e) {
callback.Hint("图片保存失败");
return false;
}
return true;
}
/**
* @return 系统根目录
*/
private String GetExternalStorageDirectory(){
return Environment.getExternalStorageDirectory().toString();
}
/**
* 根据实时 时间生成图片名称
* @return
*/
@SuppressLint("SimpleDateFormat")
private static String getStringToday() {
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String dateString = formatter.format(currentTime);
return dateString;
}
/**
* 获取图片大小
* <br>
* 在Android API(12)之前的版本和后来的版本是不一样
* @param bitmap
* @return
*/
public int getBitmapSize(Bitmap bitmap){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
return bitmap.getAllocationByteCount();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1){
return bitmap.getByteCount();
}
return bitmap.getRowBytes() * bitmap.getHeight();
}
/**
* 自定义获取图片大小并降低图片质量
* @param context
* @param uri 图片uri
* @param size 自定义图片大小
* @return
* @throws FileNotFoundException
* @throws IOException
*/
public Bitmap getThumbnail(Context context,Uri uri,int size) throws FileNotFoundException, IOException{
InputStream input =context.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither=true;
onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_4444;
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1))
return null;
int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;
double ratio = (originalSize > size) ? (originalSize / size) : 1.0;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither=true;
bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_4444;
input =context.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}
private static int getPowerOfTwoForSampleRatio(double ratio){
int k = Integer.highestOneBit((int)Math.floor(ratio));
if(k==0) return 1;
else return k;
}
/**
* 压缩图片
* @param image
* @return
*/
private Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
while ( baos.toByteArray().length / 1024>100) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
}
简单的使用例子:
import com.example.mytoolutils.utils.PhotoUtils;
import com.example.mytoolutils.utils.PhotoUtils.ProblemCallback;
import com.example.mytoolutils.utils.ToastUtil;
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.ImageView;
public class TakePhotoActivity extends Activity implements OnClickListener {
private ImageView takephoto;
private PhotoUtils photoutils;
/** 拍照*/
private final int TAKE_PHOTO=1011;
/** 相册*/
private final int PHOTO_ABLUM=1022;
/** 拍照裁剪*/
private final int CLIP_PHOTO_CREAM=1033;
/** 相册裁剪*/
private final int CLIP_PHOTO_ABLUM=1044;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_take_photo);
initview();
}
private void initview() {
photoutils=PhotoUtils.Initialize(this);
findViewById(R.id.takephotobutton).setOnClickListener(this);
findViewById(R.id.photoablumbutton).setOnClickListener(this);
findViewById(R.id.photoablumclip).setOnClickListener(this);
takephoto=(ImageView) findViewById(R.id.takephoto);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.takephotobutton:
photoutils.OpenCamera(TAKE_PHOTO);
break;
case R.id.photoablumbutton:
photoutils.OpenPhotoAlbum(PHOTO_ABLUM);
case R.id.photoablumclip:
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode==RESULT_OK){
switch (requestCode) {
case TAKE_PHOTO:
photoutils.DealWithUsualData(data, TAKE_PHOTO, "huditest", "测试图片名.jpg", callback);
photoutils.ClipBitmapWithCamera(takephoto.getWidth(),takephoto.getHeight(), CLIP_PHOTO_CREAM);
break;
case PHOTO_ABLUM:
photoutils.DealWithUsualData(data, PHOTO_ABLUM, null, null, callback);
break;
case CLIP_PHOTO_ABLUM:
photoutils.DealWithClipData(data, callback);
break;
case CLIP_PHOTO_CREAM:
photoutils.DealWithClipData(data, callback);
break;
default:
break;
}
}else{
ToastUtil.showShortToast(this, "失败");
}
}
@Override
protected void onDestroy() {
photoutils.ClearBitmap();
super.onDestroy();
};
ProblemCallback callback=new ProblemCallback() {
@Override
public void Hint(String text) {
ToastUtil.showShortToast(TakePhotoActivity.this, text);
}
@Override
public void GetBitmapSuccess(Bitmap bitmap) {
takephoto.setImageBitmap(bitmap);
}
};
}
activity_take_photo.xml:
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.example.mytoolutils.TakePhotoActivity" >
<Button
android:id="@+id/takephotobutton"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:text="拍照" />
<Button
android:id="@+id/photoablumbutton"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:text="相册" />
<Button
android:id="@+id/photoablumclip"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:text="相册选取裁剪" />
<ImageView
android:id="@+id/takephoto"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>