Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

System.NullReferenceException: CrossMedia.Current.PickPhotoAsync. (HEIC/IPhoneX) #452

Closed
christophedelanghe opened this issue Jan 26, 2018 · 8 comments

Comments

@christophedelanghe
Copy link

I get a null reference exception in the CrossMedia.Current.PickPhotoAsync when selecting a picture from the library. It only happens with some pictures.

I can't pinpoint which files go wrong but I think it might have something to do with the new HEIC format. It's also possible that it goes wrong with pictures taken on an iPhoneX.

Version Number of Plugin: 3.1.3
Device Tested On: iPhoneX

await CrossMedia.Current.Initialize();
if (CrossMedia.Current.IsPickPhotoSupported)
{
    var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions());

    if (file != null)
    {
        profilePicture.Source = ImageSource.FromStream(() =>
        {
            var stream = file.GetStream();
            return stream;
        });
    }
}

Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
at Plugin.Media.MediaPickerDelegate+d__25.MoveNext () [0x00380] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in :0
at Plugin.Media.MediaPickerDelegate+d__9.MoveNext () [0x000d4] in :0

@christophedelanghe
Copy link
Author

WEIRD ... when I pass CompressionQuality=99 to the Plugin.Media.Abstractions.PickMediaOptions it does not crash anymore ...

@jamesmontemagno
Copy link
Owner

Can you pull down the source code and run through the test apps and try to reproduce. I don't have an iphone x

@christophedelanghe
Copy link
Author

christophedelanghe commented Jan 29, 2018

The exception is in the MediaPickerDelegate line 370 ...

image.AsJPEG(quality).Save(path, true);

the image is not null, quality=1 and the path is also correct ...

if passing 0.9 as quality there is no exception

When I split up the code in two lines I can see that image.AsJPEG(quality); returns null

if (!savedImage)
{
    var jpg = image.AsJPEG(quality);
   jpg.Save(path, true);
}

jpg = null

@jamesmontemagno
Copy link
Owner

Interesting, what if you do .99?

@christophedelanghe
Copy link
Author

.99 is working also ...

@jamesmontemagno
Copy link
Owner

Do you happen to know what the file extension is on it? Curious if i can put some sort of hack in there. I don't have any devices that take these photos.

@christophedelanghe
Copy link
Author

It's just jpg ...

Maybe you can do something with the data from the CGImage?

BitmapInfo: NoneSkipLast
BitsPerComponent: 8
BytesPerRow: 16128
Height: 3024
Width: 4032

I found this post. It might have something to do with the image size, which is too big to use as JPG, according to this post:
https://stackoverflow.com/questions/15120589/uiimage-aspng-and-asjpeg-fails

The AsJPEG returned null because the image size was too big (it was taken with an iPhone 5). After I Scaled it down by 2, it generates the data properly.

This fixed it (but I don't know if it's good performance wise)

private bool SaveImageWithMetadata(UIImage image, float quality, NSDictionary meta, string path)
{
        try
        {
             var imageData = image.AsJPEG(quality);
             while (imageData == null && quality > 0)
             {
                 quality-=0.01f;
                 imageData= image.AsJPEG(quality);
             }

...

jamesmontemagno added a commit that referenced this issue Feb 1, 2018
In 3 places when trying to convert to jpeg we need to adjust quality
@jamesmontemagno
Copy link
Owner

Awesome! Good one!

Very tricky. I am pushing out: 3.1.3.222-beta

Can you test this out. The AsJPEG code is in 3 different places.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants