关闭

Android调用系统的相机,图库,以及裁剪图片功能。

标签: android相机图库裁剪
632人阅读 评论(0) 收藏 举报
分类:

在开发中,调用系统的相机拍照,或者图库选择图片是很常见的操作,有时候你会看到有的应用在选择图片的时候,会有个小方框,可以进行图片的裁剪选择,其实,这些都可以通过调用系统来实现。

1:调用系统的相机拍照。

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
在onActivityResult中,可以通过data来得到bitmap。

//      Bundle extras = data.getExtras();
//      Bitmap imageBitmap = (Bitmap) extras.get("data");
这个bitmap是个缩略图,意义不大,我们肯定希望能拿到拍照的原图。这个时候,需要传递一个File的实例,也就是照片保存的路径。

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {

            }
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
                startActivityForResult(takePictureIntent, requestCode);
            }
        }
private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        mCurrentPhotoPath = image.getAbsolutePath();
        Log.i(TAG,mCurrentPhotoPath);
        return image;
    }
其中,mCurrentPhotoPath就是拍照保存的路径,在onActivityResult中就可以获取图片,进行操作了。

2:调用系统的图库,选择图片。(在onActivityResult中通过URI来处理)

        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, requestCode);
Uri photoUri = data.getData();
                    if (photoUri != null) {
                        String[] proj = { MediaStore.Images.Media.DATA };
                        Cursor actualimagecursor = managedQuery(photoUri, proj,
                                null, null, null);
                        try {
                            int index = actualimagecursor
                                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                            actualimagecursor.moveToFirst();
                            String img_path = actualimagecursor.getString(index);
                            mCurrentPhotoPath = img_path;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

3:调用系统的裁剪:

有的app在选择用户头像的时候,可以进行裁剪,其实系统本身就自带了,就是在拍照完或者选择完图库后,通过Intent了实现的。

public void zoomPhoto(){
        Intent intent = new Intent("com.android.camera.action.CROP");
        File f = new File(mCurrentPhotoPath);
        Uri contentUri = Uri.fromFile(f);
        intent.setDataAndType(contentUri, "image/*");

        // crop为true是设置在开启的intent中设置显示的view可以剪裁
        intent.putExtra("crop", "true");

        // 设置不能改变裁减大小框
        intent.putExtra("scale", true);
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);

        // outputX,outputY 是剪裁图片的宽高
        intent.putExtra("outputX", 600);
        intent.putExtra("outputY", 600);

        // true:不返回uri,false:返回uri
        intent.putExtra("return-data", false);

        //保存裁剪的图片文件,在onActivityResult中返回的bitmap是个小的缩略图,三星测试的时候返回160*160的。
        //所有这里使用File保存,如知道原因或本人代码bug,请告知。谢谢。
        intent.putExtra("output", Uri.fromFile(tempFile));

        startActivityForResult(intent, REQUEST_CUT_PHOTO_SIZE);
    }

好了,通过上面的3段说明,已经可以在app中完成经常看到的需求了。

这个时候,你发现自己刚才拍的图片很不错,分享到朋友圈吧,让大家瞅瞅,然后打开微信,死活找不到这张图片,那是因为我们再onActivityResult中没有处理。在拍完照后,需要进行刷新。

    /**
     * 触发系统的Media Scanner,将我们的照片添加到Media Provider的数据库中,
     * 这样就可以使得Android相册程序与其他程序能够读取到这些照片
     */
    private void galleryAddPic() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(mCurrentPhotoPath);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }


这样,整个流程就都已经完成了,下面是需要注意的几个地方。

1:图片需要进行缩放操作,避免OOM。

2:网上有的说,在图库选择图片的时候,可以直接传递缩放的intent参数,在三星note3上,可以正常使用,但是在mx4的测试中,却出现了问题,不能正常打开裁剪界面,最后还是还拍照一样处理,就OK了。

3:startActivityForResult中,requestCode不能小于0,如果小于0,是不会调用onActivityResult方法的。

4:不要忘记清单文件中权限的添加,对内存卡进行了操作。


最后,附上一个.java的代码,里面包含了上面的代码,没有整个工程。Android调用系统的相机,图库,以及裁剪图片功能。





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9214次
    • 积分:244
    • 等级:
    • 排名:千里之外
    • 原创:14篇
    • 转载:0篇
    • 译文:2篇
    • 评论:0条
    文章分类