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?
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...
}
Harold Sota