相机图片Uri null路径

时间:2015-06-15 15:32:49

标签: android image

在我的应用中,我让用户有机会获得照片并将其设置为个人资料照片。有两种方法可以从图库中获取照片,也可以直接使用相机拍摄照片。

我编写的代码与booth方法一起使用,我已经在使用棒棒糖5.0的Galaxy S5上进行了测试。使用KitKat 4.4.4进行测试时,它会抛出一个NPE。但是直接从相机拍摄照片时就会抛出这个NPE。

在展位案例中,这是我遵循的结构:

  1. 从onActivityResult呼叫数据中获取Uri。
  2. 获取pic方向值(在某些情况下,纵向图像在imageview中显示为旋转)。
  3. 对位图进行解码以缩小它的纵横比。
  4. 如果图像方向错误,请旋转图像。
  5. 将位图保存在内部应用数据中。
  6. 这是“从相机拍照”请求的代码:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case TAKE_PHOTO_REQUEST_FRAG:
                if (resultCode == getActivity().RESULT_OK && data != null) {
    
                    Uri selectedImageUri = data.getData();
                    Bitmap srcBmp = null;
    
                    /*Get image orientation*/
                    int orientation = getImageOrientation(getActivity(), selectedImageUri);
                    Log.d("IMAGE_ORIENTATION", String.valueOf(orientation));
    
                    /*Downsize bitmap mantaining aspect ratio*/
                    srcBmp = decodeSampledBitmapFromUri(
                            selectedImageUri,
                            pic_view.getWidth(), pic_view.getHeight());
    
                    /*Rotate image if needed*/
                    if (orientation == 90) {
                        Matrix matrix = new Matrix();
                        matrix.postRotate(90);
                        srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
                                srcBmp.getWidth(), srcBmp.getHeight(), matrix,
                                true);
                    }
                    else if (orientation == 180) {
                        Matrix matrix = new Matrix();
                        matrix.postRotate(180);
                        srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
                                srcBmp.getWidth(), srcBmp.getHeight(), matrix,
                                true);
                    }
                    else if (orientation == 270) {
                        Matrix matrix = new Matrix();
                        matrix.postRotate(270);
                        srcBmp = Bitmap.createBitmap(srcBmp, 0, 0,
                                srcBmp.getWidth(), srcBmp.getHeight(), matrix,
                                true);
                    }
    
                    /*Save bitmap in internal memory*/
                    ContextWrapper cw1 = new ContextWrapper(getActivity().getApplicationContext());
                    File directory1 = cw1.getDir("profile", Context.MODE_PRIVATE);
                    if (!directory1.exists()) {
                        directory1.mkdir();
                    }
                    File filepath1 = new File(directory1, "profile_pic.png");
                    FileOutputStream fos1 = null;
                    try {
                        fos1 = new FileOutputStream(filepath1);
                        srcBmp.compress(Bitmap.CompressFormat.JPEG, 90, fos1);
                        fos1.close();
                    } catch (Exception e) {
                        Log.e("SAVE_FULL_IMAGE", e.getMessage(), e);
                    }
    
                    /*Show image in imageview*/
                    pic_view.setImageBitmap(srcBmp);
                }
                break;
        }
    }
    

    -

    /*Downsize the bitmap from uri*/
    public Bitmap decodeSampledBitmapFromUri(Uri uri, int reqWidth, int reqHeight) {
        Bitmap bm = null;
        try{
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(uri), null, options);
    
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            bm = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(uri), null, options);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(getActivity().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
        }
        return bm;
    }
    
    
    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
    
        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float)height / (float)reqHeight);
            } else {
                inSampleSize = Math.round((float)width / (float)reqWidth);
            }
        }
        return inSampleSize;
    }
    

    -

    /*Get image orientation first from Exif info*/
    public int getImageOrientation(Context context, Uri photoUri) {
        int orientation = getOrientationFromExif(photoUri);
        if(orientation <= 0) {
            orientation = getOrientationFromMediaStore(context, photoUri);
        }
        return orientation;
    }
    
    private int getOrientationFromExif(Uri photoUri) {
        int orientation = -1;
        try {
            ExifInterface exif = new ExifInterface(photoUri.getPath());
            int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
    
            switch (exifOrientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    orientation = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    orientation = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    orientation = 90;
                    break;
                case ExifInterface.ORIENTATION_NORMAL:
                    orientation = 0;
                    break;
                default:
                    break;
            }
        } catch (IOException e) {
            Log.e("EXIF_ORIENTATION", "Unable to get image exif orientation", e);
        }
        return orientation;
    }
    
    /* normal landscape: 0
     * normal portrait: 90
     * upside-down landscape: 180
     * upside-down portrait: 270
     * image not found: -1
     */
    private static int getOrientationFromMediaStore(Context context, Uri photoUri) {
        String[] projection = {MediaStore.Images.ImageColumns.ORIENTATION};
        Cursor cursor = context.getContentResolver().query(photoUri, projection, null, null, null);
    
        try {
            if (cursor.moveToFirst()) {
                return cursor.getInt(0);
            } else {
                return -1;
            }
        } finally {
            cursor.close();
        }
    }
    

    将NPE放在我想从exif数据中获取图像方向的行中,正好是从uri获取路径的地方:

    ExifInterface exif = new ExifInterface(photoUri.getPath());
    

    所以我知道它必须与路径有关。我已经发了几篇关于kitkat以不同格式返回路径的帖子。我尝试过不同的自定义getPath()方法,但在调用Cursor时总是抛出NPE。

1 个答案:

答案 0 :(得分:0)

  

所以我知道它必须与路径有关。

那是因为它不是文件系统路径。 A Uri is not a file,当你在其他地方正确处理时,你在这里没有这样做。

您需要切换到可以处理InputStream的EXIF逻辑,例如this code culled from the AOSP Mms app