摄像头像素乌里空路径 [英] Camera picture Uri null path

查看:155
本文介绍了摄像头像素乌里空路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序,我让用户有机会得到一张照片,并将其设置为个人资料照片。有2种方式获取的照片,从画廊,并直接用相机拍摄。

我已经写了code,与展台的方法工作的,我已经测试的银河S5棒棒糖5.0。当与奇巧4.4.4测试它,它抛出一个NPE。但引发此NPE只是直接从相机拍照时。

在展台的情况下,这是我按照结构:

  1. 从onActivityResult呼叫数据获取的URI。
  2. 在获取PIC取向值(在某些情况下,画像形象出现在ImageView的旋转)。
  3. 在德$ C C位图$缩减它mantaining宽高比。
  4. 旋转图像,如果有错误的方向。
  5. 保存位图在内部应用程序的数据。

这是这是$ C $下的拍照的相机的要求:

  @覆盖
公共无效onActivityResult(INT申请code,INT结果code,意图数据){
    super.onActivityResult(要求code,因此code,数据);
    开关(要求code){
        案例TAKE_PHOTO_REQUEST_FRAG:
            如果(结果code == getActivity()RESULT_OK和放大器;&放大器;数据!= NULL){

                乌里selectedImageUri = data.getData();
                位图srcBmp = NULL;

                / *获取图像方向* /
                INT方向= getImageOrientation(getActivity(),selectedImageUri);
                Log.d(IMAGE_ORIENTATION,将String.valueOf(取向));

                / *缩小位图mantaining宽高比* /
                srcBmp =去codeSampledBitmapFromUri(
                        selectedImageUri,
                        pic_view.getWidth(),pic_view.getHeight());

                如果需要的话/ *旋转图像* /
                如果(定向== 90){
                    字模=新的Matrix();
                    matrix.postRotate(90);
                    srcBmp = Bitmap.createBitmap(srcBmp,0,0,
                            srcBmp.getWidth(),srcBmp.getHeight(),矩阵,
                            真正);
                }
                否则,如果(定向== 180){
                    字模=新的Matrix();
                    matrix.postRotate(180);
                    srcBmp = Bitmap.createBitmap(srcBmp,0,0,
                            srcBmp.getWidth(),srcBmp.getHeight(),矩阵,
                            真正);
                }
                否则,如果(定向== 270){
                    字模=新的Matrix();
                    matrix.postRotate(270);
                    srcBmp = Bitmap.createBitmap(srcBmp,0,0,
                            srcBmp.getWidth(),srcBmp.getHeight(),矩阵,
                            真正);
                }

                / *位图保存在内存中* /
                ContextWrapper CW1 =新ContextWrapper(getActivity()getApplicationContext());
                文件directory1中= cw1.getDir(个人资料,Context.MODE_PRIVATE);
                如果(!directory1.exists()){
                    directory1.mkdir();
                }
                文件fil​​epath1 =新的文件(directory1中,profile_pic.png);
                FileOutputStream中fos1 = NULL;
                尝试 {
                    fos1 =新的FileOutputStream(filepath1);
                    srcBmp.com preSS(Bitmap.Com pressFormat.JPEG,90,fos1);
                    fos1.close();
                }赶上(例外五){
                    Log.e(SAVE_FULL_IMAGE,e.getMessage(),E);
                }

                / *在ImageView的显示图像* /
                pic_view.setImageBitmap(srcBmp);
            }
            打破;
    }
}
 

-

  / *缩减从URI位图* /
公共位图德codeSampledBitmapFromUri(URI URI,诠释reqWidth,诠释reqHeight){
    位图BM = NULL;
    尝试{
        //第一代code与inJustDe codeBounds = true来检查尺寸
        最后BitmapFactory.Options选项=新BitmapFactory.Options();
        options.inJustDe codeBounds = TRUE;
        BitmapFactory.de codeStream(getActivity()getContentResolver()openInputStream(URI),空,选项。);

        //计算inSampleSize
        options.inSampleSize = calculateInSampleSize(选项,reqWidth,reqHeight);

        与inSampleSize集//德code位图
        options.inJustDe codeBounds = FALSE;
        BM = BitmapFactory.de codeStream(getActivity()getContentResolver()openInputStream(URI),空,选项。);
    }赶上(FileNotFoundException异常E){
        e.printStackTrace();
        Toast.makeText(getActivity()getApplicationContext(),e.​​toString(),Toast.LENGTH_LONG。).show();
    }
    返回BM;
}


公众诠释calculateInSampleSize(BitmapFactory.Options选项,诠释reqWidth,诠释reqHeight){
    //原始高度和宽度的图像
    最终诠释身高= options.outHeight;
    最终诠释宽度= options.outWidth;
    INT inSampleSize = 1;

    如果(高度> reqHeight ||宽度GT; reqWidth){
        如果(宽>高度){
            inSampleSize = Math.round((浮动)的高度/(浮点)reqHeight);
        } 其他 {
            inSampleSize = Math.round((浮点)宽/(浮点)reqWidth);
        }
    }
    返回inSampleSize;
}
 

-

  / *先获取图像方向,从EXIF信息* /
公众诠释getImageOrientation(上下文的背景下,乌里photoUri){
    INT方向= getOrientationFromExif(photoUri);
    如果(定向< = 0){
        方向= getOrientationFromMediaStore(背景下,photoUri);
    }
    返回的方向;
}

私人诠释getOrientationFromExif(URI photoUri){
    INT方向= -1;
    尝试 {
        ExifInterface EXIF​​ =新ExifInterface(photoUri.getPath());
        INT exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        开关(exifOrientation){
            案例ExifInterface.ORIENTATION_ROTATE_270:
                定向= 270;
                打破;
            案例ExifInterface.ORIENTATION_ROTATE_180:
                定向= 180;
                打破;
            案例ExifInterface.ORIENTATION_ROTATE_90:
                定向= 90;
                打破;
            案例ExifInterface.ORIENTATION_NORMAL:
                定向= 0;
                打破;
            默认:
                打破;
        }
    }赶上(IOException异常E){
        Log.e(EXIF_ORIENTATION,无法获取图片EXIF方向,E);
    }
    返回的方向;
}

/ *正常景观:0
 *正常的肖像:90
 *颠倒景观:180
 *倒置纵向:270
 *没有找到图片:-1
 * /
私有静态诠释getOrientationFromMediaStore(上下文的背景下,乌里photoUri){
    的String []投影= {MediaStore.Images.ImageColumns.ORIENTATION};
    光标光标= context.getContentResolver()查询(photoUri,投影,NULL,NULL,NULL);

    尝试 {
        如果(cursor.moveToFirst()){
            返回cursor.getInt(0);
        } 其他 {
            返回-1;
        }
    } 最后 {
        cursor.close();
    }
}
 

这是扔在NPE在我想从EXIF数据的图像方向行,正是我从URI获取路径:

  ExifInterface EXIF​​ =新ExifInterface(photoUri.getPath());
 

所以,我知道,它必须是一些与路径。我已经readed几个职位有关奇巧返回一个diferent格式的路径。我曾尝试diferent定制getPath()方法,但调用光标时总是会引发NPE。

解决方案
  

所以,我知道这一定有什么用路径。

这是因为它不是一个文件系统路径。 A 乌里不是一个文件,而你正在处理的正确别处,你不这样做在这里。

您需要切换到EXIF逻辑可以处理的InputStream 等的这code从AOSP彩信应用扑杀。

In my app, I let the user the chance to get a photo and set it as profile pic. There are 2 ways for getting the photo, from the gallery, and directly taken with the camera.

I have wrote code that works with booth methods, and I have tested on a Galaxy S5 with lollipop 5.0. When testing it with a KitKat 4.4.4, it is throwing a NPE. But is throwing this NPE just when taking the photo directly from the camera.

In booth cases, this is the structure I follow:

  1. Get the Uri from the onActivityResult call data.
  2. Get pic orientation value (in some cases the portrait image appears rotated in the imageview).
  3. Decode the bitmap to downsize it mantaining the aspect ratio.
  4. Rotate the image if it has the wrong orientation.
  5. Save the bitmap in the internal app data.

An this is the code for the "take photo from camera" request:

@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();
    }
}

It is throwing the NPE in the line where I want to get the image orientation from the exif data, exactly where I get the Path from the uri:

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

So I know that it must be something with the path. I have readed several posts about that kitkat returns the path in a diferent format. I have tried diferent custom getPath() methods, but always throws NPE when calling the Cursor.

解决方案

So I know that it must be something with the path.

That's because it's not a filesystem path. A Uri is not a file, and while you are handling that properly elsewhere, you are not doing so here.

You need to switch to EXIF logic that can handle an InputStream, such as this code culled from the AOSP Mms app.

这篇关于摄像头像素乌里空路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆