Xamarin Android 无法从旋转后的图像中读取 EXIF 数据来检查图像是否旋转

问题描述 投票:0回答:3

描述

根据方向旋转读取 EXIF 元数据来检查图像是否旋转,然后创建新的位图并将其设置为 ImageView 控件。

实际图像 EXIF 数据:

[C#]

    protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            ImageView image = new ImageView(this);
            var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.test);
            ExifInterface originalMetadata;
            using (var stream = new MemoryStream())
            {
                bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, stream);
                originalMetadata = new ExifInterface(stream);
            }

            int orientation = GetRotation(originalMetadata);

            Matrix matrix = new Matrix();
            if (orientation != 0)
            {
                matrix.PreRotate(orientation);
                bitmap = Bitmap.CreateBitmap(bitmap, 0, 0, bitmap.Width, bitmap.Height, matrix, true);
            }
            image.SetImageBitmap(bitmap);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);
        }

预期行为

读取旋转图像ExifData以获取方向。基于方向旋转然后创建新的位图并设置到 ImageView 控件。

实际行为

获取 ExifData 方向值为 0。

基本信息

测试设备为华为PRA、Infinix Pro

环境

Visual Studio 2019

截图

image

示例链接

图像演示.zip

有什么办法可以解决这个问题吗?

c# android xamarin xamarin.forms xamarin.android
3个回答
1
投票

var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.test);

现在你有了一个位图。

但是位图不包含 exif 标头或方向信息。

将该位图压缩到流中,然后让 Exifinterface 从该流中读取。

bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, 流);

originalMetadata = new ExifInterface(stream);

但是由于位图不包含 exif 信息或方向信息,因此流也没有它们。

所以没有有效的 exif 信息,也没有方向信息。没什么。

相反,您应该从原始资源文件中读取 exif 信息。


1
投票

首先,正如blackapps上面所说,当你将图片解码为Bitmap后,Exif信息将会丢失。

其次,android中的

Resources/
通常指的是资源。
ExifInterface
仅从文件系统加载文件,而不是资源。毕竟,开发人员想要在资源上使用
ExifInterface
是完全没有意义的。资源是只读的,因此您无法使用
ExifInterface
修改资源中的 EXIF 标头。开发人员不会浪费用户的时间、CPU 和电池读取只读图像文件来提取元数据,而是提前这样做,将数据放在其他地方。

所以你可以将

test.jpg
移动到
Assets
文件夹中,然后使用你的方法获取其EXIF数据:

var stream = Assets.Open("test.jpg");
originalMetadata = new ExifInterface(stream);
int orientation = GetRotation(originalMetadata);

0
投票
**Xamarin.Android Project: Retrieving Image Rotation Angle**

This code snippet demonstrates how to extract the image rotation angle from a stream using the ExifInterface class from the Xamarin.AndroidX.ExifInterface NuGet package:

public int GetImageRotationAngle(Stream stream)
{
  try
  {
    var exif = new ExifInterface(stream);
    int orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, ExifInterface.OrientationUndefined);
    switch (orientation)
    {
      case ExifInterface.OrientationRotate90:
        return 90;
      case ExifInterface.OrientationRotate180:
        return 180;
      case ExifInterface.OrientationRotate270:
        return 270;
      default:
        return 0;
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine($"Error in GetImageRoatation -> {ex}");
    return 0;
  }
}

**Explanation:**

 1. GetImageRotationAngle(Stream stream): This method takes a Stream object containing the image data as input.

 2. var exif = new ExifInterface(stream);: Creates a new ExifInterface instance using the provided stream.

 3. int orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, ExifInterface.OrientationUndefined);: Retrieves the orientation value from the EXIF data using the TagOrientation constant. If the tag is not found, ExifInterface.OrientationUndefined (0) is returned.

 4. switch (orientation): A switch statement interprets the retrieved orientation value:
ExifInterface.OrientationRotate90: Indicates a 90-degree clockwise rotation.
ExifInterface.OrientationRotate180: Indicates a 180-degree rotation.
ExifInterface.OrientationRotate270: Indicates a 270-degree clockwise rotation.
default: If the orientation value is not recognized, a 0-degree rotation is assumed.

 5. Exception Handling: The code includes a try-catch block to handle potential exceptions during the EXIF data access. If an error occurs, it logs the error message and returns 0 for rotation angle.

**Important Note:**

Ensure you're using the Xamarin.AndroidX.ExifInterface NuGet package for compatibility with the latest AndroidX libraries. Avoid using the older Android.Media.ExifInterface as it might have compatibility issues.
© www.soinside.com 2019 - 2024. All rights reserved.