【问题标题】:Xamarin Android can't read EXIF data from the rotated image to check whether the image rotated or notXamarin Android 无法从旋转的图像中读取 EXIF 数据以检查图像是否旋转
【发布时间】:2021-03-02 10:02:29
【问题描述】:

说明

通过读取基于方向旋转的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

截图

示例链接

ImageDemo.zip

有没有办法解决这个问题?

【问题讨论】:

  • 你验证过图片是否真的包含EXIF数据吗?
  • 是的,实际图像包含 Exif 数据。

标签: c# android xamarin xamarin.forms xamarin.android


【解决方案1】:

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

现在你有了一个位图。

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

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

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

originalMetadata = new ExifInterface(stream);

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

所以没有有效的 exif 信息和方向信息。什么都没有。

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

【讨论】:

    【解决方案2】:

    首先,正如上面的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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      相关资源
      最近更新 更多