调用系统相册,相机

调用系统相册获取图片(大图片可以选择裁剪),系统相机拍照保存并裁剪:

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);//600
        intent.putExtra("outputY", 200);//300
        intent.putExtra("scale", true);
        intent.putExtra("return-data", true);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true); // no face detection
        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");  
        //裁剪框的比例,1:1  
        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();
            //此方法在图片过大时不可取  取的是原图片  会造成内存泄露
            //  bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),imageUri);
            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) {
        //判断是否有sd卡
        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));  
            /*  //判断图片大小 对大图片进行压缩, 质量过大容易引起oom
            if(getBitmapSize(bitmap)>bitmapsize){
                //50 是压缩率,表示压缩50%; 如果不压缩是100,表示压缩率为0 
                LogUtils.i("正在压缩图片"+getBitmapSize(bitmap)+","+bitmapsize);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos); 
            }else{
                LogUtils.i("不压缩图片");
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            }*/
            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){    //API 19
            return bitmap.getAllocationByteCount();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1){//API 12
            return bitmap.getByteCount();
        }
        return bitmap.getRowBytes() * bitmap.getHeight();                //earlier version
    }
    /**
     * 自定义获取图片大小并降低图片质量
     * @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;//optional
        /*  Android中有四种,分别是:
        ALPHA_8:每个像素占用1byte内存
        ARGB_4444:每个像素占用2byte内存
        ARGB_8888:每个像素占用4byte内存
        RGB_565:每个像素占用2byte内存*/
        onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_4444;//optional
        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;//optional
        bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_4444;//optional
        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);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中  
        int options = 100;  
        while ( baos.toByteArray().length / 1024>100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩         
            baos.reset();//重置baos即清空baos  
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中  
            options -= 10;//每次都减少10  
        }  
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中  
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片  
        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:
//          photoutils.ClipBitmapfromphotoalbum(CLIP_PHOTO_ABLUM);
            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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值