Xamarin.Forms 应用程序中的 ExifInterface 方向始终为 0

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

我正在开发 Xamarin.Forms 应用程序,我想在其中实现拍照功能。

我已经实现了这个功能及其工作原理。但刚才我在三星设备上遇到了一个问题。因此,当我从设备拍照时,它会自动旋转。但同样的行为在 Moto X 等其他设备上也能完美运行。

为了解决这个问题,我正在检查该图像的 ExifInterface,但不知何故它始终为 0。

对于拍照,我的代码片段如下:

            var image = await CrossMedia.Current.TakePhotoAsync (new Plugin.Media.Abstractions.StoreCameraMediaOptions {
            Directory = "../Library",
            Name = ImageFilename
        });

然后为了获得方向,

var exifInterface = new ExifInterface (image.Path);
        int orientation = exifInterface.GetAttributeInt (ExifInterface.TagOrientation, 0);

但是如果我检查方向,那么它总是 0。

我还在 exifInterface.GetAttributeInt 中传递了 -1,但它也给出了 0。

有人遇到过这样的问题吗?还是我在这里做错了什么?

xamarin xamarin.android xamarin.forms
2个回答
0
投票

您使用什么版本的

CrossMedia
2.4.0-beta1

中修复了类似问题

您使用的是什么设备?有些设备自然是横向的(例如三星 Galaxy Tab S4),这可能会导致图像的方向和当前旋转问题。


0
投票
Xamarin.Forms: Rotate Image After Taking Photo

There are two approaches to rotate an image captured with the camera in Xamarin.Forms, depending on your preference:

1. Using CrossMedia Plugin (Simple):

If you're using the CrossMedia plugin for capturing photos, you can leverage the StoreCameraMediaOptions object within the TakePhotoAsync method. Set the RotateImage property to true to automatically rotate the captured image:

var storeOptions = new StoreCameraMediaOptions
{
    RotateImage = true,
    // Other options...
};

var result = await CrossMedia.Current.TakePhotoAsync(storeOptions);

2. Using MediaPicker and Exif (More Control):

This approach offers finer control over image rotation. It involves:

MediaPicker: Used to capture the photo in Xamarin.Forms.
ExifInterface (AndroidX.ExifInterface.Media NuGet): Reads the image's orientation data on Android. (Important: Use the AndroidX library, not the older Android.Media version)
SkiaSharp (Latest NuGet): Rotates the image based on the orientation data.
Steps:

a. Android Implementation (using DependencyService):
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;
    }
}

b. Shared Code Implementation:
var photo = await MediaPicker.CapturePhotoAsync();
await LoadPhotoAsync(photo, path); // Replace 'path' with image file path

async Task LoadPhotoAsync(FileResult photo, string path)
{
    try
    {
        using (var stream = await photo.OpenReadAsync())
        {
            using (var fileStream = File.Open(path, FileMode.OpenOrCreate))
            {
                var RIS = DependencyService.Get<IImageRotator>();
                var rotationAngle = RIS.GetImageRotationAngle(stream);
                var finalStream = await photo.OpenReadAsync();

                if (rotationAngle > 0)
                {
                    var bitmap = SKBitmap.Decode(finalStream);
                    SKBitmap photoBitmap = RotateBitmap(bitmap, rotationAngle);
                    Stream rotatedStream = SKImage.FromBitmap(photoBitmap).Encode().AsStream();

                    rotatedStream.CopyTo(fileStream);
                    rotatedStream.Flush();
                    return;
                }

                finalStream.CopyTo(fileStream);
                finalStream.Flush();
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error in LoadPhotoAsync() => {ex}");
    }
}

private SKBitmap RotateBitmap(SKBitmap bitmap, float angle)
{
    SKBitmap rotatedBitmap = new SKBitmap(bitmap.Height, bitmap.Width);
    using (var surface = new SKCanvas(rotatedBitmap))
    {
        surface.Translate(rotatedBitmap.Width, 0);
        surface.RotateDegrees(angle);
        surface.DrawBitmap(bitmap, 0, 0);
    }
    return rotatedBitmap;
}

c. Interface for DependencyService (optional):
public interface IImageRotator
{
    int GetImageRotationAngle(Stream stream);
}

Finally,
The CrossMedia plugin offers a simpler solution, while the MediaPicker and Exif approach provides more control over the rotation process.
© www.soinside.com 2019 - 2024. All rights reserved.