Android - 确保在通过 Camera Intent 拍照时保留照片方向?
Android - Ensuring that photo orientation is preserved when taking photos via Camera Intent?
我正在构建一个 Android 应用程序,用户可以在其中拍照,然后将照片保存到某个文件路径。使用相机意图并将结果保存到自定义文件路径以及在 ImageView 中将其显示给用户没有任何问题。但是,我最近在多个设备上测试它时遇到了一个奇怪的行为。
每当我拍摄肖像照片时,我都会得到风景照片。
这是我使用的代码:
public void onTakePhoto(View view){
//camera stuff
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//folder stuff
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "folderHere");
imagesFolder.mkdirs();
File image = new File(imagesFolder, timeStamp + ".png");
Uri uriSavedImage = Uri.fromFile(image);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
这将打开相机并拍摄 1 张照片。拍摄 1 次后,用户可选择重试拍照。我发现对于某些设备,即使我拍摄肖像照片,输出也会变成风景。我已将 activity 的方向设置为纵向。
到目前为止我为获得结果所做的工作,使用 Exif 文件确定旋转,然后相应地旋转它(如我遇到的问题的一些答案中所述)。然而,这里的问题是这需要一些时间,在我回到我在 ImageView 中看到它的 activity 之前,我得到了 3-4 秒的黑屏。
这是我使用的旋转代码:
File为String中的文件路径
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = null;
try {
exif = new ExifInterface(file);
} catch (IOException e) {
Log.e(TAG, "exception hit while making exif!", e);
}
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
FileOutputStream out = null;
try {
out = new FileOutputStream(imagePath);
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
Log.e(TAG, "exception hit while exporting!", e);
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
是否有可靠的方法来确保在保存照片时相机的方向得到保留?如果相机是纵向的,那么结果也应该是纵向的,横向也是如此。
我一直在四处寻找,但运气不佳。我能想到的一个解决方案是,也许我们可以将一些东西与相机意图一起传递,比如旋转常量或其他东西,这样输出就不会被弄乱,我们就能得到我们想要的方向。
Is there a reliable way of making sure that the orientation of the camera gets preserved when saving the photo?
没有
首先,您将拍照委托给 third-party 应用,这是数千种可能的相机应用之一。那些开发者可以为所欲为。
其次,其根本原因来自相机硬件和固件。您无法告诉某些芯片组旋转图像而不是使用 EXIF 方向 header.
我正在构建一个 Android 应用程序,用户可以在其中拍照,然后将照片保存到某个文件路径。使用相机意图并将结果保存到自定义文件路径以及在 ImageView 中将其显示给用户没有任何问题。但是,我最近在多个设备上测试它时遇到了一个奇怪的行为。
每当我拍摄肖像照片时,我都会得到风景照片。
这是我使用的代码:
public void onTakePhoto(View view){
//camera stuff
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//folder stuff
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "folderHere");
imagesFolder.mkdirs();
File image = new File(imagesFolder, timeStamp + ".png");
Uri uriSavedImage = Uri.fromFile(image);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(imageIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
这将打开相机并拍摄 1 张照片。拍摄 1 次后,用户可选择重试拍照。我发现对于某些设备,即使我拍摄肖像照片,输出也会变成风景。我已将 activity 的方向设置为纵向。
到目前为止我为获得结果所做的工作,使用 Exif 文件确定旋转,然后相应地旋转它(如我遇到的问题的一些答案中所述)。然而,这里的问题是这需要一些时间,在我回到我在 ImageView 中看到它的 activity 之前,我得到了 3-4 秒的黑屏。
这是我使用的旋转代码:
File为String中的文件路径
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = null;
try {
exif = new ExifInterface(file);
} catch (IOException e) {
Log.e(TAG, "exception hit while making exif!", e);
}
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
FileOutputStream out = null;
try {
out = new FileOutputStream(imagePath);
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
Log.e(TAG, "exception hit while exporting!", e);
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
是否有可靠的方法来确保在保存照片时相机的方向得到保留?如果相机是纵向的,那么结果也应该是纵向的,横向也是如此。
我一直在四处寻找,但运气不佳。我能想到的一个解决方案是,也许我们可以将一些东西与相机意图一起传递,比如旋转常量或其他东西,这样输出就不会被弄乱,我们就能得到我们想要的方向。
Is there a reliable way of making sure that the orientation of the camera gets preserved when saving the photo?
没有
首先,您将拍照委托给 third-party 应用,这是数千种可能的相机应用之一。那些开发者可以为所欲为。
其次,其根本原因来自相机硬件和固件。您无法告诉某些芯片组旋转图像而不是使用 EXIF 方向 header.