Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[image_picker] iOS: save image to the correct type based on its original type and copy over exif data from the original image #1586

Merged
merged 2 commits into from
May 20, 2019

Conversation

cyanglaz
Copy link
Contributor

@cyanglaz cyanglaz commented May 9, 2019

Description

Previously, our implementation checks the alpha of the UIImage object to determine the type (png or jpeg). This PR refactored the code to actually check the original image file's type to determine the type it should be saved. Which makes it safer.

While doing so, we also copied the exif data from the original image, now the picked image has the correct exif data.

Since iOS doesn't support converting UIImage to NSData for types other than PNG or JPEG, we are currently only supporting these 2 types. (If anyone knows how to convert UIImage to other types:gif or tiff, we can add them as well)

XCTests target is also added in this PR. So we can start adding iOS unit tests in image picker.

This is a follow up of #742
And this PR is the first step to achieve what we were trying to do in #866.

Thanks to @ko2ic for inspiration of some of the works in this PR.

We will need follow up PR to support GIF if possible, as well as copying GPS data over.

Related Issues

flutter/flutter#31751
flutter/flutter#17947
flutter/flutter#12921

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See Contributor Guide).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the Flutter Style Guide.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the CLA.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@cyanglaz cyanglaz force-pushed the image_picker_ios_file_type_refactor branch from 640715f to 8dc06ef Compare May 9, 2019 20:22
@cyanglaz
Copy link
Contributor Author

cyanglaz commented May 9, 2019

@ko2ic This PR is inspired by your PR in #866
Do you mind review this? :)

@cyanglaz cyanglaz changed the title [image_picker] iOS: save image to different types based on its original type. [image_picker] iOS: save image to the correct type based on its original type. May 9, 2019
Copy link
Contributor

@ko2ic ko2ic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyanglaz It's getting really good.

I have made some comments.
I think especially gif can be supported.

AUTHORS Outdated
Ozkan Eksi <ozeksi@gmail.com>
ko2ic <ko2ic.sal@gmail.com>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the e-mail address below.

ko2ic <ko2ic.dev@gmail.com>

NSData *data = [ImagePickerMetaDataUtil convertImage:image
usingType:type
quality:nil];
NSString *fileExtension = [@"image_picker_%@" stringByAppendingString:suffix];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of type == FlutterImagePickerMIMETypeOther, suffix will be nil.
Therefore, a crash occurs.

It is more convenient to treat as jpeg than not to support FlutterImagePickerMIMETypeOther.

// quality with type other than FlutterImagePickerMIMETypeJPEG. Converting UIImage to
// FlutterImagePickerMIMETypeGIF or FlutterImagePickerMIMETypeTIFF is not supported in iOS. This
// method throws exception if trying to do so.
+ (nonnull NSData *)convertImage:(nonnull UIImage *)image
Copy link
Contributor

@ko2ic ko2ic May 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the argument type here is not UIImage but NSData, it can handle gif images.

Please refer to the following.

https://github.com/flutter/plugins/pull/866/files#diff-ce2e9c98db20f69ecf981788585d7a87R209

This will be able to also handle animated gif.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can add the gif handling in a separate PR. I also want to take a deeper dive into the implementation to see if there is a way to support scaling gif. If not, then we need to decide how to handle when people passed the scaling factors into the API.

@cyanglaz cyanglaz changed the title [image_picker] iOS: save image to the correct type based on its original type. [image_picker] iOS: save image to the correct type based on its original type and copy over exif data from the original image May 14, 2019
@cyanglaz
Copy link
Contributor Author

cyanglaz commented May 14, 2019

@ko2ic Thanks for doing this. I updated the PR with you comments! I also added the exif in this PR. Do you mind to take another look?

Copy link
Contributor

@ko2ic ko2ic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyanglaz I tried it, but the creationDate of Exif is different.
Timezone seems to be irrelevant.
It gets as 16 hours ago.

@cyanglaz
Copy link
Contributor Author

@ko2ic That's strange, all I did was just copying everything over, I will take a look again.

@cyanglaz
Copy link
Contributor Author

@ko2ic I just checked and it seems working for me? Could you post the steps of your testing here?

@ko2ic
Copy link
Contributor

ko2ic commented May 16, 2019

@cyanglaz It works without problem in unit test but I get problems when I run it on the simulator.

I put a breakpoint on line 31 in ImagePickerPhotoAssetUtil.m and I confirmed ExifDateTimeOriginal.
The selected image is an image in the simulator.

Please check the image below.

create_date

@cyanglaz
Copy link
Contributor Author

@ko2ic Thank you. I tested with the steps you provided and I found out that the time that shows up in photo app in the simulator does depend on the time zone of your computer. Somehow the time in the metadata is based on Pacific time and it just matched my local time. If you set your mac to pacific timezone, and reopen the photo app in the simulator, you will see the time match the time in the exif.

@ko2ic
Copy link
Contributor

ko2ic commented May 16, 2019

@cyanglaz I do not mind if this is a problem with mac and simulator.

@cyanglaz
Copy link
Contributor Author

@ko2ic Thanks! Other than that, do you see any issues or improvements that can be done in the code?

@ko2ic
Copy link
Contributor

ko2ic commented May 20, 2019

@cyanglaz No problem. Please go ahead and proceed with it.

@cyanglaz cyanglaz merged commit 7c23d31 into flutter:master May 20, 2019
@cyanglaz cyanglaz deleted the image_picker_ios_file_type_refactor branch May 20, 2019 20:42
cyanglaz pushed a commit that referenced this pull request May 22, 2019
Follow up #1586. Copying over all the metadata, including GPS, orientation and more.

Note that because orientation is copied, we have to revert the orientation that iOS has done on the picked image to make the image show up in a correct way on the phone.
julianscheel pushed a commit to jusst-engineering/plugins that referenced this pull request Mar 11, 2020
* iOS: Using first byte to determine original image type. (Only JPEG and PNG)
* iOS: Added XCTest target.
* iOS: The picked image now has the correct EXIF data copied from the original image.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants