【问题标题】:Android - Ensuring that photo orientation is preserved when taking photos via Camera Intent?Android - 确保通过相机意图拍照时保留照片方向?
【发布时间】:2016-10-06 13:02:03
【问题描述】:

我正在构建一个 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 次拍摄后,用户可以选择重试拍照。我发现对于某些设备,即使我拍摄肖像照片,输出也会变成风景。我已将活动的方向设置为纵向。

到目前为止,我为获得结果所做的工作,使用 Exif 文件确定旋转,然后相应地旋转它(在我遇到的问题的一些答案中如此详细)。但是,这里的问题是这需要一些时间,在我回到我在 ImageView 中看到的活动之前,我会出现 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();
    }
}

是否有可靠的方法来确保在保存照片时保留相机的方向?如果相机是纵向的,那么结果也应该是纵向的,横向也是如此。

我一直在环顾四周,但运气不佳。我能想到的一个解决方案是,也许我们可以将一些东西与相机意图一起传递,比如旋转常数或其他东西,这样输出就不会被弄乱,我们会得到我们想要的方向。

【问题讨论】:

  • 我使用过的所有 Android 相机始终将数据保存为宽 x 高,而不是高 x 宽。为您提供正确的方向是 EXIF 数据的工作。我认为您的问题是您用于旋转图像的任何代码都太慢了-您能给我们一个示例吗?
  • @npace:Android 设备硬件/固件在方向方面的行为会有所不同。某些设备(如大多数 Nexus 设备)会保存根据拍摄照片时设备方向旋转的图像。其他设备,如大多数三星设备,将图像保存为横向,并根据拍摄照片时的设备方向设置 EXIF 标题。应用程序可以尝试对此进行规范化,但很多都没有。
  • @npace 更新了我的问题。
  • @CommonsWare 有用的评论。我忘记了一些设备以正确的方向保存图像,因为编写代码来处理三星的方向问题隐藏了一些理智的工程......

标签: android android-intent camera android-camera android-camera-intent


【解决方案1】:

是否有可靠的方法来确保在保存照片时保留相机的方向?

没有。

首先,您将拍照委托给第三方应用程序,这是数千种可能的相机应用程序之一。这些开发人员可以为所欲为。

其次,造成这种情况的根本原因来自相机硬件和固件。您无法告诉某些芯片组旋转图像而不是使用 EXIF 方向标头。

【讨论】:

  • 1.我正在使用本机相机应用程序。 2. 所以没有可靠的方法来确保原生相机不会因为旋转而把你搞砸?您只需要依赖输出,获取 EXIF 方向标头,然后根据需要旋转?
  • @Razgriz:“我正在使用本机相机应用程序”——首先,有数千种 Android 设备型号,其中预装了数百种不同的相机应用程序。其次,您使用“本机相机应用程序”,而是使用ACTION_IMAGE_CAPTURE。第三方应用程序可以提供支持,用户可以选择使用其中之一。因此,您正在与数以千计的可能的相机应用程序集成,并且每个应用程序的行为都会有所不同,具体取决于他们的开发人员选择做什么。
  • @Razgriz:“所以没有可靠的方法来确保本机相机不会因为旋转而把你搞砸?” - 同样,您没有使用“本机相机”。第三方应用程序做什么取决于他们。它们中的许多将简单地存储相机 API 为它们提供的任何内容,并且 在图像方向(实际数据和 EXIF 标头)方面因硬件而异。 “你只需要依靠输出,获取 EXIF 方向标头,然后根据需要旋转?” - 正确的。这与您从任意其他来源获取图像没有什么不同。
  • @Razgriz: This sample app 演示了解决此问题的两种方法:旋转实际的 Bitmap 和旋转 ImageView
  • @Razgriz:如果您控制服务器,请让服务器查看 EXIF 标头并在那里旋转图像。如果您不控制服务器,您可能会同时使用这两种技术:旋转 ImageView 进行显示,而在后台旋转 Bitmap 作为上传过程的一部分。
猜你喜欢
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多