Android图片裁剪解决方案 -- 从相册截图

在看Storage Access Framework,里面有一个加载相册图片的程序片断,可能是系统版本的问题,无法返回结果,这里找到一个适用于旧版本的方法。

 

在Android开发中,可以轻松调用一个Intent完成从相册中截图的工作:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");

附加选项如下:

选项 数据类型 描述
crop String 发送裁剪信号
aspectX int X方向上的比例
aspectY int Y方向上的比例
outputX int 裁剪区的宽
outputY int 裁剪区的高
scale boolean 是否保留比例
return-data boolean 是否将数据保留在Bitmap中返回
data Parcelable 相应的Bitmap数据
circleCrop String 圆形裁剪区域?
MediaStore.EXTRA_OUTPUT ("output") URI 将URI指向相应的 file:///...

 

这个return-data是比较令人困惑的。

有两种方法接收截图数据:

方法一:把return-data设为true,让数据直接通过Intent返回到onActivityResult中,如下:

public void SelectSmallImg(View view){
        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", 800);
        intent.putExtra("outputY", 800);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", true);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true); // no face detection
        startActivityForResult(intent, CHOOSE_SMALL_PICTURE);
    }

方法二:return-data设为false,利用MediaStore.EXTRA_OUTPUT标签,把数据存储在外部的临时URI,再由onActivityResult读取。当然了,要事先准备好一个指向文件的URI,如果有sdcard则问题不大,没有的话会怎样?????

public void SelectLargeImg(View view){
        // this is for android 4.4 ??
        //Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        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", 400);  //返回数据的时候的 X 像素大小。
        //intent.putExtra("outputY", 400);  //返回的时候 Y 的像素大小。
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent,CHOOSE_BIG_PICTURE);
    }

在onActivityResult里可以这样对付:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent resultData){
        switch(requestCode){
            case CHOOSE_BIG_PICTURE:
                if(resultCode == Activity.RESULT_OK && resultData != null){
                    Log.i(DEBUG_FLAG,imageUri.toString());
                    Bitmap bitmap = decodeUriAsBitmap(imageUri);//decode bitmap (自己写一个把URI转换为bitmap的函数)
                    if(bitmap == null){
                        Log.i(DEBUG_FLAG,"BIG_PICTURE NULL");
                    }else{
                        imageView.setImageBitmap(bitmap);
                        Log.i(DEBUG_FLAG , "Size:"+bitmap.getWidth()+" X "+bitmap.getHeight());
                    }
                    
                }
                break;
            case CHOOSE_SMALL_PICTURE:
                if(resultCode == Activity.RESULT_OK && resultData != null){
                    Bitmap bitmap = resultData.getParcelableExtra("data");
                    if(bitmap == null){
                        Log.i(DEBUG_FLAG,"SMALL_PICTURE NULL");
                    }else{
                        imageView.setImageBitmap(bitmap);
                        Log.i(DEBUG_FLAG , "Size:"+bitmap.getWidth()+" X "+bitmap.getHeight());
                    }
                }
                break;
            default :
                break;
        }
    }

自己写一个把URI转换为bitmap的函数:

Bitmap decodeUriAsBitmap(Uri uri){
            Bitmap bitmap = null;
            try {
                bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            }
            return bitmap;
    }

============================

总结一下:基于内存的考虑,在图片较大时,android的截图功能会返回一个160*160的缩略图,这样就只能通过外部URI来接收数据,如果是小图,直接用Intent传递数据是没问题的。

 

本文大部分参考:http://blog.csdn.net/floodingfire/article/details/8144615

API指南中的Storage Access Framework是基于API4.4的版本,里面的最后部分有一个关于自定义Document Provider的构建,这里也要记录一下。(例如是自己实现的云存储)

 

 

 

 

posted @ 2015-04-15 11:04  myjhaha  阅读(399)  评论(0编辑  收藏  举报