MediaPicker.Default.CapturePhotoAsync returning PNG in .NET 10 and JPEG in .NET 9


I have a .NET 9 Maui app that takes photos on Android. Using MediaPicker.Default.CapturePhotoAsync. Photos were often rotated by 90 degrees. However, they were JPEGs with EXIF data intact. I learned a bit about this and found some example code and used it orientate the photos correctly. I was a happy bunny.

I am now targetting .NET 10. There are additional options to pass to CapturePhotoAsync, among them is MediaPickerOptions.RotateImage. When set to true my interpretation of the documentation is that it will yield correctly orientated images and I don't need to worry about this any more. Not true. They are wrongly oriented. What is more, the image provided is a PNG without EXIF data. When set to false, I still get a PNG but it is the right way up. This seems worryingly random and not documented.

Can I assume that if RotateImage is false I will always get a correctly oriented image? If not, it seems my app has taken a retrograde step by upgrading .NET.

I call it like this

FileResult? photo = await MediaPicker.Default.CapturePhotoAsync(BuildPhotoOptions());

Where BuildPhotoOptions is

private static MediaPickerOptions BuildPhotoOptions(string ? title = null) {
  var max = Constants.MaxPhotoHeightOrWidthPixels;

  return new MediaPickerOptions {
    Title = title,
    SelectionLimit = 1, // can't rely on this
    // MaximumWidth = max,
    // MaximumHeight = max,
    CompressionQuality = 95,
    RotateImage = false,
    PreserveMetaData = true
  };
}

I've been consulting ChatGPT. It says "You’re right to demand certainty here — and the uncomfortable truth is: with MediaPicker.Default.CapturePhotoAsync you cannot guarantee either the output format (JPEG vs PNG) or whether the pixels are already rotated. The picker is allowed to hand you a processed/transcoded copy." Is it correct?

3
Jan 30 at 8:05 AM
User AvatarIan
#android#.net#maui

Accepted Answer

ChatGPT is partially correct but overly pessimistic. Let me clarify what's actually happening:

When RotateImage = true:

  • The platform applies rotation to the pixel data based on EXIF orientation

  • EXIF orientation metadata is typically stripped (hence PNG output without EXIF)

  • The image should be correctly oriented, but you're experiencing bugs

When RotateImage = false:

  • The platform should preserve the original image as-is

  • EXIF data should be preserved (when PreserveMetaData = true)

  • No pixel rotation should occur

The fact that you're getting:

  • PNG output (instead of JPEG)

  • Wrong orientation with RotateImage = true

  • Correct orientation with RotateImage = false

Since RotateImage = false + PreserveMetaData = true is giving you correctly oriented images, I'd recommend:

private static MediaPickerOptions BuildPhotoOptions(string? title = null)
{
    return new MediaPickerOptions
    {
        Title = title,
        CompressionQuality = 95,
        RotateImage = false,  // Keep this
        PreserveMetaData = true  // Keep this
    };
}

Then always read and apply EXIF orientation yourself after capture:

FileResult? photo = await MediaPicker.Default.CapturePhotoAsync(BuildPhotoOptions());

if (photo != null)
{
    // Read the stream and apply EXIF orientation
    using var stream = await photo.OpenReadAsync();
    var correctedImage = ApplyExifOrientation(stream);
    // Use correctedImage...
}
User AvatarHarold Sota
Jan 30 at 11:34 AM
1