question

WeiWen-3421 avatar image
0 Votes"
WeiWen-3421 asked JarvanZhang-MSFT edited

Photos taken using MediaPicker.CapturePhotoAsync are rotated 90 degrees

This is the case for both Android and iOS. Because of this, I have to rotate the image. I did this on Android with this code:

[assembly:Xamarin.Forms.Dependency(typeof(ImageService))]
namespace KnowMobile.Droid.DependencyServices
{
public class ImageService : IImageUtil
{
private int GetImageRotation(string filePath)
{
try
{
ExifInterface ei = new ExifInterface(filePath);
Orientation orientation = (Orientation)ei.GetAttributeInt(ExifInterface.TagOrientation, (int)Orientation.Undefined);
switch (orientation)
{
case Orientation.Rotate90:
return 90;
case Orientation.Rotate180:
return 180;
case Orientation.Rotate270:
return 270;
default:
return 0;
}
}
catch (Exception ex)
{
return 0;
}
}

 public byte[] RotateImage(System.IO.Stream imageStream, string filePath)
 {
   int rotationDegrees = GetImageRotation(filePath);
   byte[] byteArray = new byte[imageStream.Length];
   try
   {
     imageStream.Read(byteArray, 0, (int)imageStream.Length);

     Bitmap originalImage = BitmapFactory.DecodeByteArray(byteArray, 0, byteArray.Length);
     Matrix matrix = new Matrix();
     matrix.PostRotate((float)rotationDegrees);

     Bitmap rotatedBitmap = Bitmap.CreateBitmap(originalImage, 0, 0, originalImage.Width,
         originalImage.Height, matrix, true);

     using (MemoryStream ms = new MemoryStream())
     {
       rotatedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, ms);
       return ms.ToArray();
     }
   }
   catch (Exception ex)
   {
     return byteArray;
   }
 }

}
}


I hope to be able to achieve the same result on iOS, if there is no way to adjust the photo orientation when using MediaPicker.CapturePhotoAsync. Any help is greatly appreciated!


A little background info for this strange behavior: Because my app only allows portrait mode, all pictures taken have larger height than width. So when rendered, they all lie on their heights. My Image's width and height are set to have a slightly larger width. But since I set its Aspect to be AspectFit, that shouldn't be the reason to change its orientation.

dotnet-xamarinforms
· 9
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, WeiWen-3421. I created a basic demo to test the function, the photo's orientation is right on Android. It's unnecessary to rotate the photo. How do you display or save the captured photo? Could you please post the related code?

If want to adjust the photo orientation, try to rotate the photo stream in the shared project using SKBitmap directly. Here is the sample code, you could refer to it.

private async void Button_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();

    if (photo == null)
    {
        return;
    }
    Stream stream = await photo.OpenReadAsync();

    SKBitmap photoBitmap = RotateBitmap(SKBitmap.Decode(stream));
    Stream rotatedStream = SKImage.FromBitmap(photoBitmap).Encode().AsStream();
}

SKBitmap RotateBitmap(SKBitmap bitmap)
{
    SKBitmap rotatedBitmap = new SKBitmap(bitmap.Height, bitmap.Width);
    using (var surface = new SKCanvas(rotatedBitmap))
    {
        surface.Translate(rotatedBitmap.Width, 0);
        surface.RotateDegrees(90);
        surface.DrawBitmap(bitmap, 0, 0);
    }
    return rotatedBitmap;
}
0 Votes 0 ·
WeiWen-3421 avatar image WeiWen-3421 JarvanZhang-MSFT ·

@JarvanZhang-MSFT Thanks for the answer. The photos that were rotated 90 degrees were taken when the device was oriented in portrait mode. I haven't test the case when the device is in landscape mode. As you can see from the function GetImageRotation, it will check if the image stored in the file is rotated and then do rotation correspondingly to change it back to the correct orientation. Simply doing the rotation without checking if the saved photo is rotated will not achieve the goal.

0 Votes 0 ·
WeiWen-3421 avatar image WeiWen-3421 JarvanZhang-MSFT ·

@JarvanZhang-MSFT I tested taking photos with the device oriented in both landscape and portrait and in both Android phone and iPhone. I am not sure if package update fixed the issue on Android or not. Now photos taken in both orientations show up properly. But in iOS, the photos taken in portrait are rotated 90 degrees and the photos taken in landscape are not rotated. So it looks like the code I posted above is not needed since Android has no issue. But I still need to fix the rotation in iOS.

0 Votes 0 ·
WeiWen-3421 avatar image WeiWen-3421 JarvanZhang-MSFT ·

@JarvanZhang-MSFT I tested photo on Android again. It turns out that even though the photo appears to oriented properly, if I didn't use the code I posted above to change photo orientation in the file, it will eventually ends up rotated 90 degree once I the file is saved in blob storage and loaded in the app.

0 Votes 0 ·

How do you save the captured images to the database? Do you save the images as stream?

Try to store the image stream to the database instead. The image could be displayed correctly with the stream.

var photo = await MediaPicker.CapturePhotoAsync();

if (photo == null)
{
    return;
}

Stream stream = await photo.OpenReadAsync();
img.Source = ImageSource.FromStream(()=> { return stream; });
0 Votes 0 ·
Show more comments

0 Answers