(Related to Issue #285 )
Not to dredge up a closed issue but we are seeing the exact same behavior as referenced in #285 with the media plugin in our forms app. We noticed that the image is displayed correctly on the screen most of the time but if you convert to a Base64String and use something like https://codebeautify.org/base64-to-image-converter to view image, the image is displayed in landscape instead of portrait.
We have two ways of storing photos. The first captures and sends the converted string to an api for storage on a DB server. The second is an offline storage mode that saves the encrypted string in a SQLLite DB on the device.
Once the image is sent to the API, for whatever reason, all photos that were captured as portrait display in landscape mode. However, decrypting and converting back to a stream from the local DB results in a correctly displayed image.
We cannot figure out why but it seems like setting the source of an image to a stream will result in a correctly oriented image most of the time. When we look at the image on the remote system however, it is always landscape.
I am having an issue where the image is always rotated to landscape if image is portrait. This happens with just picking the image from the camera roll. I am picking the image (var file = await CrossMedia.Current.PickPhotoAsync();), and immediately throwing it into a Image object source property either as GetStream() or Path. The result is always a landscape rotated image. If the image was originally landscape, no rotation happens.
Oh, this also ONLY happens in iOS. My Android project using the exact same code is properly orientated.
We do see it happening consistently on all iOS devices. It doesn't seem to be a problem on our development Pixel and we are trying it out on other Android models to see if we can confirm an iOS only problem well. We do know that it happens on the android emulator.
Are you sure that you aren't stripping off the metadata/exif data when you encode it. Additionally, when you send it up to the server and it is displayed is it respecting the exif data? What you want to do is pull it down, look at exif data and see if it is correct or not.
The problem is that I am taking the file right from the CrossMedia.Current.PickPhotoAsync() call and pushing it directly into a Image using both ImageSource.FromStream(() => file.GetStream()) as well as ImageSource.FromFile(file.Path) and both ways show the image turned landscape.
I ended up having to write my own image picker code, and when it selects the image, I am having to manually rotate the image to the proper orientation based on UIImage.Orientation and using CGContext and transforms. This works great but I was hoping to use this library for code reusability. Unfortunately, only Android seems unaffected by this image rotation situation.
I even updated to the latest beta in nuget and it still didn't fix this issue.
So in this instance I actually do absolutely 0 rotation on iOS or UWP at all. I only do re-sizing.
Most likely the image is correct and the rendering is not using the exif data. You could simply try FFImageLoading, which does.
Some people want me to rotate the image and others do not at all. I simply add the exif data to the images so you are in control. @tacoman667 you should send in a PR for the functionality as there is a "RotateImage" property that we can check. It would go somewhere around here: https://github.com/jamesmontemagno/MediaPlugin/blob/master/src/Media.Plugin.iOS/MediaPickerDelegate.cs#L268 and then we need to update the metadata.
@jamesmontemagno
The problem isn't that you aren't rotating the image, it's that Apple has decided that all images are captured in the exact same orientation regardless of actual rotation. It looks like the first orientation state is your device turned into landscape counterclockwise. This means that if one takes a picture in the portrait orientation, that is saves in the counterclockwise-landscape orientation and some kind of metadata applied to the image telling it the orientation to move it to in order to be the orientation it was originally taken.
I do not understand why this is. Seems weird as hell to me and so confusing that there are a lot of developers in my search that seem to have the same issue I was having; I take a picture in portrait and I expect it to be saved in portrait. Now, I am by no means an expert or even close to it in photography and software design around that industry, but it would be nice to have a flag in the MediaStoreOptions object that I can set to retrieve the image and rotate it to the expected orientation that the image was originally captured in. There was a RotateImage flag on the object currently, and it looked like it should respect the originating orientation and it's always set to true. If I set this flag to false, Android will turn it's images to landscape as well. So either this flag is already there and broken for iOS, or the feature may not have been fully completed when it was merged into, at least, 3.0.1 which was the first version I picked up and used.
Edit:
It looks like that flag was introduced to android implementation and not for iOS other than to set it from options, hence my confusion as to why it didn't work.
I also getting this issue, please fix
@tacoman667: Can you propose a temp hack for this issue? I see this on iOS explicitly. I have tried all the solutions proposed in issues list. Below are some links none of them works
https://forums.xamarin.com/discussion/comment/248469#Comment_248469
https://github.com/jamesmontemagno/MediaPlugin/issues/268
https://github.com/jamesmontemagno/MediaPlugin/issues/166
All the PhotoSize & compressionquality solutions: Never worked
Actually, I wrote a CustomRenderer on the ios side and am using that instead of this plugin. Only for iOS. for android, I let the app continue with this for now.
The code makes ios open the camera, or open the picker in a popover controller.
Do you want to help contribute at all?
I would like to fix things in the plugin :)
Sure! I have been a bit swamped with Harvey lately.. When I get a chance, I'll fork and get to work on it.
Have you got any news about the fix? I also have the same problem. Thanks
Yeah. I already have a PR out there for weeks. Just waiting on it to be merged.
Watching this issue now. I only see this happening on iOS 11.
Thanks, my report:
I have the same problem, only on iOS (I am able to try only with iOS11), and with version 3.0.2.129-beta
Thanks
I have a fix merged in, but it seems there are some unexpected issues that popped up. I haven't had the time yet, but will be investigating.
I guess this issue is not related to iOS 11. I have 2 versions of my app. First one compiled with MediaPlugin 2.6.2 and XCode 8 - it is working fine on iOS 11. The second one compiled with MediaPlugin 3.0.1 and XCode 9 - this one not working on iOS 11.
@bprochniak Are you just taking a pic and showing it on the screen? My scenario is explicitly that I am sending the stream to an API, which then later I get it back and the exif data is not persisted on the server so the orientation is completely off.
If showing an image that was/is stored on the device after being taken, then this plugin works perfectly fine.
Taking a pic and showing it on screen works fine to me, only when I pick a portrait photo from the device gallery and show it on the screen, the photo's orientation gets changed from Portrait to Landscape but not every picture. Some of portrait photos works fine. I described it here:
https://github.com/jamesmontemagno/MediaPlugin/issues/371
I think this is another case but it was marked as duplicated.
This is weird. When I edit a portrait picture (on iPhone, it does not matter what I change), save it and then pick it from the device gallery it works fine.
I confirm, with MediaPlugin 2.6.2 version it works
@bprochniak Are the affected images ones taken from an older iphone from a while back? Maybe in an older version of iOS? I'm curious if those images are missing some metadata about orientation or something.
Since, I think, iOS 10, orientation is metadata on the image data saved with the image. All images are the same orientation when taken, but saved with the data of how it needs to be "turned" when presented in a UIImage. This is why I am having such a hard time with sending these images to my API, then reading them from the API and the orientation is never "turned" correctly, thus images are shown in the original orientation of the camera lens/sensor. This scenario is what I fixed in the PRs I submitted and are merged.
Are the affected images ones taken from an older iphone from a while back? Maybe in an older
version of iOS? I'm curious if those images are missing some metadata about orientation or
something.
@tacoman667 No, all the images were taken on iOS 11
@tacoman667 i added a new feature flag in this PR to turn off saving exif data... would return to how 2.6.x did it (3.0 introduced exif re-saving)
@jamesmontemagno Was it not saving before? At first glance, it looks like it was. However, it will save only if the images were taken with this plugin right?
And this really doesn't affect the situation where we need to push the image to an external source? Probably because the external source is probably not an Apple device and thus may not have the ability to save such metadata, thus losing the orientation data?
@tacoman667 the metadata re-save was added in 3.0 and apparently that may be causing issue for people. IDK, every camera on android is different nad iOS is always crazy.
Hi all! Sorry, I didn't get if this issue fixed or not. I am using Media Plugin version _3.0.2.129-beta_ and still has the same problem. Could you please clarify? Thanks in advance.
@fabasoad The changes I submitted are in master, so I am not sure if it's been deployed yet. One fo the lines I added for this issue was https://github.com/jamesmontemagno/MediaPlugin/blob/c95c21432f841f7e352681d4647a7e810e0d1ec9/src/Media.Plugin.Abstractions/MediaFile.cs#L77
Thank you, @tacoman667!
I see that this fix was merged in scope of PR #374 12 days ago. The latest at this moment build is _3.0.2.129-beta_ which was built 20 days ago. So it seems this fix didn't get into the build.
@jamesmontemagno do you have any ETA when the next build (beta or not) will be ready? Thanks in advance.
Just checked. The new 3.0.2.175-beta build was added 9 hours ago. Thanks.
GetStreamWithImageRotatedForExternalStorage fixed this issue for me. iOS images are now not rotated 90 clockwise. Thanks!
For me too. Thanks.
Tested on multiple devices, and on my iPhone 6s the portrait images are still rotated.
Tested also with v2.6.2 of the plugin, and then it works fine on all devices.
3.0.2.175-beta does not work on my iPhone 6 with iOS 11.0.1 (images rotated). v2.6.2 works fine.
@plumbingtheos Well, it's an early beta, still, so I wouldn't be surprised if it's not working yet.
@bprochniak Are you using the new method for GetStreamForExternalStorage()?
I've tested v3.0.2.181-beta on iPhone6s with iOS11.1, landscape and portait images are shown perfectly inside Image object of Xamarin.Forms.
Thanks!
I am getting UIKit Consistency errors in v3.0.2.181-beta
Is there an earlier beta that has this fixed?
@duzenko yes in next build
.188 beta appears to have fixed it
Hi!
I've installed .193-beta. Worked well with Release but in Debug (Android) got
12-14 14:46:33.614 I/MonoDroid( 9109): UNHANDLED EXCEPTION:
12-14 14:46:33.661 I/MonoDroid( 9109): System.MissingMethodException: Method 'Plugin.Media.Abstractions.MediaFile.GetStreamWithImageRotatedForExternalStorage' not found.
Seems like maybe you have some nuget issues, you can remove and re-add
Yep! Was that! Thanks, James!
Same problem with 3.1.3 everything works fine, but if I try to catch a photo with iOS Camera, on Android ( and only on Android ) is rotate -90CW, on iOS is ok. The problem occur only when I take a photo on iOS and i view the Photo on an Android device.
If i take photos on Android and upload to my server then the photos are fine. However on iOS they are always in landscape even if taken in portrait mode. I am using the setting RotateImage = true, and GetStreamWithImageRotate...etc() .... But they make no difference to the orientation with photos taken on iOS...
I'm experiencing the same as @gviddy. Images taken on android are fine, but iOS images are rotated.
Tested on iPad Pro, iOS 11.2, MediaPlugin 3.1.3
Interestingly enough, this issue only happens for us for photos either picked or taken on iOS (Android is fine). On any iOS device, this image will display fine, however on any Android or Web device (using base64 string) - the image appears to be rotated.
I've also tried this on the newest pre-release (3.1.3.222) however the issue still remains.
Image captured on Android
Android Display: Okay
iOS Display : Okay
Web Display (base64) : Okay
Image Selected on Android
Android Display: Okay
iOS Display: Okay
Web Display (base64) : Okay
Image Captured on iOS
Android Display: Rotated
iOS Display: Okay
Web Display(base64): Rotated
Image Selected on iOS
Android Display: Rotated
iOS Display: Okay
Web Display(base64): Rotated
Tested with..
MediaPlugin 3.1.3,
iOS 11.2 iPad Pro,
Samsung Galaxy S8,
Samsung Galaxy S8+,
Web browser (custom application) reading the base64 image.
Our code - Passed the image control (to update the 'confirm image', and a page for referencing where to use DisplayAlert.
public static async Task<byte[]> GetImage(Image ImageXAMLControl,ContentPage page)
{
if (await page.DisplayAlert("Choose Source", "Take new image or choose from Gallery?", "New Photo", "Gallery"))
{
return await ImageFromCamera(ImageXAMLControl);
}
else
{
return await ImageFromGallery(ImageXAMLControl);
}
}
ImageFromCamera method, similar method for ImageFromGallery (uses PickPhotoAsync instead).
As you can see, it's using GetStreamWithImageRotatedForExternalStorage when getting the stream. Previously using just GetStream - but this modification seems to be making no difference for us.
private static async Task<byte[]> ImageFromCamera(Image ImageXAMLControl)
{
try
{
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.TakePhotoAsync(
new StoreCameraMediaOptions
{
SaveToAlbum = true,
PhotoSize = PhotoSize.Medium,
CompressionQuality = 92
});
if (file == null)
{
return new byte[0];
//return;
}
//https://github.com/jamesmontemagno/MediaPlugin/issues/333
//was just GetStream, iOS rotate issue
ImageXAMLControl.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStreamWithImageRotatedForExternalStorage();
return stream;
});
byte[] byteImage;
using (var memoryStream = new MemoryStream())
{
file.GetStream().CopyTo(memoryStream);
byteImage = memoryStream.ToArray();
file.Dispose();
}
return byteImage;
}
catch(Exception ex)
{
return null;
}
}
I have same issue in iOS 12.1.2 with Media plugin 4.0.1.5 any fix regarding this issue
@jamesmontemagno @tacoman667
I have same issue in iOS 13.3.1(the photos are rotated counterclockwise) and in Android ,the Landscape images are changing to Portrait mode with Media plugin 4.1.1 any fix regarding this issue
Currently with the 5.01.1 still having this issue.
UPDATE: I missed seeing the fix, by using GetStreamForExternalStorage() this was resolved
Most helpful comment
Thank you, @tacoman667!
I see that this fix was merged in scope of PR #374 12 days ago. The latest at this moment build is _3.0.2.129-beta_ which was built 20 days ago. So it seems this fix didn't get into the build.
@jamesmontemagno do you have any ETA when the next build (beta or not) will be ready? Thanks in advance.