摄像头像素乌里空路径 [英] Camera picture Uri null path
问题描述
在我的应用程序,我让用户有机会得到一张照片,并将其设置为个人资料照片。有2种方式获取的照片,从画廊,并直接用相机拍摄。
我已经写了code,与展台的方法工作的,我已经测试的银河S5棒棒糖5.0。当与奇巧4.4.4测试它,它抛出一个NPE。但引发此NPE只是直接从相机拍照时。
在展台的情况下,这是我按照结构:
- 从onActivityResult呼叫数据获取的URI。
- 在获取PIC取向值(在某些情况下,画像形象出现在ImageView的旋转)。
- 在德$ C C位图$缩减它mantaining宽高比。
- 旋转图像,如果有错误的方向。
- 保存位图在内部应用程序的数据。
这是这是$ 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();
}
文件filepath1 =新的文件(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:
- Get the Uri from the onActivityResult call data.
- Get pic orientation value (in some cases the portrait image appears rotated in the imageview).
- Decode the bitmap to downsize it mantaining the aspect ratio.
- Rotate the image if it has the wrong orientation.
- 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屋!