在 activity 上旋转从图库中选择的图像,结果在 android 上旋转
Get rotation of an image selected from the gallery on activity result on android
这个问题似乎经常出现,我已经阅读了很多关于这个主题的文章是错误的,所以我想阅读并更正它,所以它总是纵向的,
我已经实现了用于启动相机、拍照和检查 Exif 数据以确保其始终为纵向的方法,但这似乎不适用于 selecting 画廊的图像,我的旋转变量将总是 return 0
ExifInterface exifInterface = new ExifInterface(imgFile.getAbsolutePath());
int rotation =
exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
System.out.println(rotation);
Matrix matrix = new Matrix();
if (rotation != 0f) {
matrix.preRotate(rotationInDegrees);
Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0,
0, bitmap.getWidth(), bitmap.getHeight(),
matrix,false);
imgView.setImageBitmap(bitmap2);
path = saveToInternalStorage(imageFileName,bitmap2,getApplicationContext());
}
else
path = saveToInternalStorage(imageFileName,bitmap,getApplicationContext());
}
catch (IOException e) {
e.printStackTrace();
}
ExifToDegrees 方法
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
}
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270; }
else if (exifOrientation == 6) {
return 90; }
else if (exifOrientation == 3) {
return 180; }
else if (exifOrientation == 8) {
return 270; }
return 0;
}
如前所述,我已经阅读了很多相关内容,有人说这是 android 的错误,有人说这是新的最近的文件选择器,我们应该使用
getAbsolutePath()
并检查每个 SDK 版本并首先保存图像,我完成所有这些并不愉快有人说我们根本不需要使用 Exif
MediaStore.Images.ImageColumns.ORIENTATION
应该可以,但还是不行。
我的目标设备是从 ICS 到 M(我拥有我需要授予的所有权限)我正在将图像保存到我的文件夹
File directory = cw.getDir("SimpleAAC", Context.MODE_PRIVATE);
并将路径保存在数据库中,我从该文件夹加载图像,使用我数据库中的路径并使用通用图像加载器,
在征得许可后,我用这个
启动了画廊
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select A Picture"), PICK_IMAGE_REQUEST);
dialog.dismiss();
这是我的画廊 onActivityResult 代码
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data !=
null && data.getData() != null) {
Uri uri = data.getData();
BitmapFactory.Options bitmapOptions = new
BitmapFactory.Options();
bitmapOptions.inSampleSize = 4;
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap scaledBitmap = BitmapFactory.decodeStream(inputStream,
null, bitmapOptions);
String timeStamp = new
SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + ".jpg";
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir("SimpleAAC", Context.MODE_PRIVATE);
File mypath = new File(directory,imageFileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//the relevant parts of this method(setThumbNailImageAndSave ) are
// included above
finalPath = setThumbnailImageAndSave(imageView,mypath);
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new
DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.ic_insert_photo_black_24dp)
.showImageOnFail(R.drawable.ic_insert_photo_black_24dp)
.showImageOnLoading(R.drawable.ic_insert_photo_black_24dp).build();
imageLoader.displayImage(finalPath, imageView, options);
System.out.println(finalPath);
}
所以为了结束这个问题,我正在寻求澄清,这是一个错误吗?我可以使用 MediaStore.Images.ImageColumns.ORIENTATION 来解决这个问题吗?如果可以,如何解决?是 intent.setAction(intent.ACTION_GET_CONTENT) 吗?是 post kitkat 文件更改了吗?
老实说,我已经阅读了很多关于此的相互矛盾的信息,但我似乎没有尝试任何工作,感谢所有回复
is this a bug?
在你的代码中?可能吧。目前尚不清楚第一个代码片段中的 imgFile
与最后一个代码片段的关系。但是在最后一个代码片段中,您通过解码位图然后对其进行编码来剥离所有 EXIF headers。如果这是您在第一个代码片段中通过 ExifInterface
检查的文件,那就是您的问题。
can i get around this using MediaStore.Images.ImageColumns.ORIENTATION and if so how?
否,因为您的图像可能不是来自 MediaStore
。
相反,给定您的 uri
,在 ContentResolver
上调用 openInputStream()
。然后,将 openInputStream()
传递给 a better ExifInterface
, one that can read from streams rather than requiring a file. This sample app 演示了该过程,包括拥有更好的 ExifInterface
代码的副本,尽管我碰巧使用了资产中的 InputStream
而不是来自ContentResolver
.
如果您出于其他原因想要制作图像的本地副本,请删除最后一个代码片段中的 decode-and-encode 位图逻辑。相反,openInputStream()
和那个 uri
,在你想要的文件上打开一个 FileOutputStream
,然后使用正常的 Java I/O 复制字节。这将使 EXIF headers 保持完整。
此外,无论哪种情况,请在后台线程上完成所有这些 Uri
工作。
这个问题似乎经常出现,我已经阅读了很多关于这个主题的文章是错误的,所以我想阅读并更正它,所以它总是纵向的, 我已经实现了用于启动相机、拍照和检查 Exif 数据以确保其始终为纵向的方法,但这似乎不适用于 selecting 画廊的图像,我的旋转变量将总是 return 0
ExifInterface exifInterface = new ExifInterface(imgFile.getAbsolutePath());
int rotation =
exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
System.out.println(rotation);
Matrix matrix = new Matrix();
if (rotation != 0f) {
matrix.preRotate(rotationInDegrees);
Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0,
0, bitmap.getWidth(), bitmap.getHeight(),
matrix,false);
imgView.setImageBitmap(bitmap2);
path = saveToInternalStorage(imageFileName,bitmap2,getApplicationContext());
}
else
path = saveToInternalStorage(imageFileName,bitmap,getApplicationContext());
}
catch (IOException e) {
e.printStackTrace();
}
ExifToDegrees 方法
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
}
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270; }
else if (exifOrientation == 6) {
return 90; }
else if (exifOrientation == 3) {
return 180; }
else if (exifOrientation == 8) {
return 270; }
return 0;
}
如前所述,我已经阅读了很多相关内容,有人说这是 android 的错误,有人说这是新的最近的文件选择器,我们应该使用
getAbsolutePath()
并检查每个 SDK 版本并首先保存图像,我完成所有这些并不愉快有人说我们根本不需要使用 Exif
MediaStore.Images.ImageColumns.ORIENTATION
应该可以,但还是不行。
我的目标设备是从 ICS 到 M(我拥有我需要授予的所有权限)我正在将图像保存到我的文件夹
File directory = cw.getDir("SimpleAAC", Context.MODE_PRIVATE);
并将路径保存在数据库中,我从该文件夹加载图像,使用我数据库中的路径并使用通用图像加载器, 在征得许可后,我用这个
启动了画廊 Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select A Picture"), PICK_IMAGE_REQUEST);
dialog.dismiss();
这是我的画廊 onActivityResult 代码
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data !=
null && data.getData() != null) {
Uri uri = data.getData();
BitmapFactory.Options bitmapOptions = new
BitmapFactory.Options();
bitmapOptions.inSampleSize = 4;
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap scaledBitmap = BitmapFactory.decodeStream(inputStream,
null, bitmapOptions);
String timeStamp = new
SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + ".jpg";
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir("SimpleAAC", Context.MODE_PRIVATE);
File mypath = new File(directory,imageFileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//the relevant parts of this method(setThumbNailImageAndSave ) are
// included above
finalPath = setThumbnailImageAndSave(imageView,mypath);
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new
DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.ic_insert_photo_black_24dp)
.showImageOnFail(R.drawable.ic_insert_photo_black_24dp)
.showImageOnLoading(R.drawable.ic_insert_photo_black_24dp).build();
imageLoader.displayImage(finalPath, imageView, options);
System.out.println(finalPath);
}
所以为了结束这个问题,我正在寻求澄清,这是一个错误吗?我可以使用 MediaStore.Images.ImageColumns.ORIENTATION 来解决这个问题吗?如果可以,如何解决?是 intent.setAction(intent.ACTION_GET_CONTENT) 吗?是 post kitkat 文件更改了吗?
老实说,我已经阅读了很多关于此的相互矛盾的信息,但我似乎没有尝试任何工作,感谢所有回复
is this a bug?
在你的代码中?可能吧。目前尚不清楚第一个代码片段中的 imgFile
与最后一个代码片段的关系。但是在最后一个代码片段中,您通过解码位图然后对其进行编码来剥离所有 EXIF headers。如果这是您在第一个代码片段中通过 ExifInterface
检查的文件,那就是您的问题。
can i get around this using MediaStore.Images.ImageColumns.ORIENTATION and if so how?
否,因为您的图像可能不是来自 MediaStore
。
相反,给定您的 uri
,在 ContentResolver
上调用 openInputStream()
。然后,将 openInputStream()
传递给 a better ExifInterface
, one that can read from streams rather than requiring a file. This sample app 演示了该过程,包括拥有更好的 ExifInterface
代码的副本,尽管我碰巧使用了资产中的 InputStream
而不是来自ContentResolver
.
如果您出于其他原因想要制作图像的本地副本,请删除最后一个代码片段中的 decode-and-encode 位图逻辑。相反,openInputStream()
和那个 uri
,在你想要的文件上打开一个 FileOutputStream
,然后使用正常的 Java I/O 复制字节。这将使 EXIF headers 保持完整。
此外,无论哪种情况,请在后台线程上完成所有这些 Uri
工作。