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

13

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

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

我曾想通过检查方向并旋转字节数组来解决问题,但肯定有更简单的方法,因为处理字节数组很麻烦。如何确保以拍摄时的方向保存照片?


请查看此处类似的问题 [https://dev59.com/J2gt5IYBdhLWcg3w-SP1]。 - DevinFalgoust
我已经看过那个答案了。我刚刚下载了他提供的源代码,实际上并不是用于相机应用程序,而是用于使用默认相机拍照。我只是不明白如何在答案中实现代码。有一个位图变量我没有。如果你知道如何在onPictureTaken中包含答案,我会接受这个答案。 - lisovaccaro
3个回答

0

可以尝试这样做:

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

获取图像数据有不同的方式,可以作为数据、流、文件等形式,并且对于相机、相册和其他应用程序也不同。对于每个方式,都有另一种访问方向标记的方法。一旦您获得了方向,就可以旋转图像。

无论是您还是其他人,都应该真正拥有 Nexus,因为它们很好地为您旋转图像并将方向设置为 0。而懒惰的像三星这样的公司则只存储图像并设置方向标记。 ;)


0
假设您正在使用{{link1: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对象作为一种简单的方式来解码和操作图像数据。
然后,我们创建一个Matrix,因为旋转是通过矩阵乘法表示的线性变换,并且我们不需要直接操作像素值。
接下来,我们使用Exif元数据来确定我们需要如何旋转图像以使其正确定向。
在为图像创建正确的旋转矩阵之后,使用新的变换Matrix和原始Bitmap创建一个新的Bitmap
最后,我们使用FileOutputStream将图像写入预定义的类成员filePath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接