确保照片以与拍摄方向相同的方向保存?

Make sure photos are saved with the same orientation they were taken?

提问人:lisovaccaro 提问时间:1/28/2013 最后编辑:lisovaccaro 更新时间:4/14/2023 访问量:1466

问:

出于某种原因,我的相机应用程序保存了所有旋转 90 度的照片(照片只有在横向模式下使用相机拍摄时才看起来正确)我相信 onPictureTaken 应该自动旋转照片,但我读到三星设备有问题(我无法在其他品牌上测试它,所以我不知道是否是这种情况)。这是我的代码:

   public void onPictureTaken(byte[] data, Camera camera) {
      // Generate file name
      FileOutputStream outStream = null;
      outStream = new FileOutputStream(filePath);
      outStream.write(data);
      outStream.close();

我认为可以通过检查方向和旋转字节数组来修复它,但必须有一种更直接的方法来做到这一点,因为处理字节数组很痛苦。 如何确保保存的照片与拍摄方向一致?

java android 相机 阵列 照片

评论

0赞 DevinFalgoust 1/29/2013
在这里看到一个类似的问题。
0赞 lisovaccaro 1/29/2013
我看到了这个答案。我刚刚下载了他提供的源代码,它实际上不是用于相机应用程序,而是用于使用默认相机拍照。我根本不明白如何在答案上实现代码。我没有位图变量。如果您知道如何将答案包含在 onPictureTaken 中,我会接受答案。

答:

0赞 GioLaq 1/30/2013 #1

尝试这样的事情:

int orientation = Exif.getOrientation(data);
Log.d("#", "onPictureTaken().orientation = " + orientation);
if(orientation != 0) {
     Bitmap bmpSrc = BitmapFactory.decodeByteArray(data, 0, data.length);
     Bitmap bmpRotated = CameraUtil.rotate(bmpSrc, orientation);
     bmpSrc.recycle();


       try {

             FileOutputStream localFileOutputStream = new FileOutputStream(filePath);
             bmpRotated.compress(Bitmap.CompressFormat.JPEG, 90,localFileOutputStream);
             localFileOutputStream.flush();
             localFileOutputStream.close();
             bmpRotated.recycle();

           }
        catch (FileNotFoundException e) 
           {
              e.printStackTrace();
           }
        catch (IOException e) 
           {
               e.printStackTrace();
           }

      } else {

          try {

               FileOutputStream localFileOutputStream = new FileOutputStream(filePath);
               localFileOutputStream.write(data);
               localFileOutputStream.flush();
               localFileOutputStream.close();

               } catch (IOException localIOException)
                  {
                                        Log.e("#",localIOException.getMessage());
                  }
   }
0赞 Kay 9/19/2014 #2

有不同的方法可以获取图像,作为数据、流、文件,相机和图库以及其他应用程序也不同。对于它们中的每一个,您都有另一种访问方向标签的方法。确定方向后,您可以旋转图像。

你 - 或者就此而言,每个人都应该真正得到一个Nexus,它们很好,可以为你旋转图像并将方向设置为0,而像三星这样的懒惰者只是存储图像并设置方向标签。;)

0赞 24tr6637 4/14/2023 #3

假设您使用的是 Android 图形框架,如下所示的内容可能适合您:

public void onPictureTaken(byte[] data, Camera camera) {
    try {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        ExifInterface exif = new ExifInterface(filePath);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.postRotate(90);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.postRotate(180);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.postRotate(270);
                break;
            default:
                break;
        }
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        FileOutputStream outStream = new FileOutputStream(filePath);
        rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  • 首先,我们可以使用 Bitmap 对象作为解码和操作图像数据的简单方法。
  • 然后我们创建一个矩阵,因为旋转是由矩阵乘法表示的线性变换,因为我们不需要直接操作像素值。
  • 然后,我们使用 Exif 元数据来确定我们需要如何旋转图像以使其正确定位。
  • 为图像创建正确的旋转矩阵后,使用新变换和原始 .BitmapMatrixBitmap
  • 最后,我们使用 FileOutputStream 将图像写入预定义的类成员。filePath