Android启动相机拍照、相册选取图片,裁剪图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29078329/article/details/78142158

    最近项目中用到了用户上传头像,需要支持相机拍照、相册选取图片,并裁剪的功能,下面记录整理一下实现过程,先上图:


一、手机拍照获取图片

    指定图片路径mCameraFile,启动相机拍照,拍摄的图片会保存在mCameraFile中:

private void selectFromCamera() {
        Uri outputFileUri = Uri.fromFile(mCameraFile);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        mActivity.startActivityForResult(intent, 1002);
    }
    mCameraFile的获取:

 /**
     * 拍照图片保存的路径
     *
     * @return
     */
    public static File createImageFile() {
        File appDir = new File(Environment.getExternalStorageDirectory(), "topNews");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置以当前时间格式为图片名称
        String fileName = df.format(new Date()) + ".jpeg";
        File file = new File(appDir, fileName);
        return file;
    }

二、onActivityResult(int requestCode, int resultCode, Intent data)中获取拍摄的图片

    private void handleCameraResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            Uri fileUri = FileUtils.getImageContentUri(this, mCameraFile);
            String imgPath = FileUtils.getImagePathWithUri(this, fileUri, null);
            Bitmap bitmap = ImageZip.decodeSampledBitmapFromFile(mFile.getAbsolutePath(),mWidth, mHeight);
        }
            
    }

   //根据图片对应的File,拿到图片的URI
    public static Uri getImageContentUri(Context context, java.io.File imageFile) {
        String filePath = imageFile.getAbsolutePath();
        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ",
                new String[]{filePath}, null);
        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

    //根据图片的URI,得到图片File的路径

    public static String getImagePathWithUri(Context context, Uri uri, String selection) {
        String path = null;
        Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

   //采样压缩,预防oom

    public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        return src;
    }


    private static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight || (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

注意在获取bitmap时,如果imagView要加载该bitmap,要对图片进行相应的压缩,防止在大图片的情况下发生OOM。


三、从相册中选取图片

    private void selectFromAlbumSingle() {
        Intent intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        mActivity.startActivityForResult(intent, 1001);
    }

四、onActivityResult(int requestCode, int resultCode, Intent data)中获取选中的图片

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       
        if (requestCode == 1001) {
            Uri uri = data.getData();
        }

    }

得到uri后,获取bitmap和相机拍照一样:


五、裁剪图片

    指定裁剪图片保存的路径mCropFile,启动系统裁剪程序进行裁剪,完成后,图片会保存在mCropFile中。

/**
     * 裁剪图片
     *
     * @param uri
     */
    public void cutPic(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        mCropFile = FileUtils.createImageFile();
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCropFile));
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", false);
        startActivityForResult(intent, 1010);
    }
 

六、获取裁剪图片

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //裁剪图片
        if (requestCode == 1010) {
            handleCutPicResult(resultCode);
        }	
    }

    private void handleCutPicResult(int resultCode) {
        if (resultCode == RESULT_OK) {
            String portraitPath = mCropFile.getAbsolutePath();
            Bitmap bitmap = BitmapFactory.decodeFile(portraitPath);
            mPortraitImg.setImageBitmap(bitmap);
        }
    }

参考:http://blog.csdn.net/gdutxiaoxu/article/details/53411790

代码地址:https://github.com/xiyy/TopNews

猜你喜欢

转载自blog.csdn.net/qq_29078329/article/details/78142158