Permalink
Browse files

Fix photo orientation from ImagePickerIOS

Summary:
Original PR: #12249

ImagePickerIOS saves photos to ImageStoreManager without meta information. So photo has wrong orientation.

**Test plan**
1. Take the 2 photos (in landspape and portrait orientation) with this code:
```
ImagePickerIOS.openCameraDialog(
  {},
  (uri) => CameraRoll.saveToCameraRoll(uri),
  () => {}
);
```
2. Ensure that photos in Photos app have right orientation.
Closes #15060

Differential Revision: D5487595

Pulled By: shergin

fbshipit-source-id: ce1a47f4d5ba33e03070f318f3d6a8dd0df5ab88
  • Loading branch information...
doochik authored and facebook-github-bot committed Jul 25, 2017
1 parent eec5823 commit 6555f9bee865af03a4db09beb9216b8b61e182b8
Showing with 27 additions and 8 deletions.
  1. +2 −2 Libraries/Image/RCTImageStoreManager.m
  2. +1 −1 Libraries/Image/RCTImageUtils.h
  3. +24 −5 Libraries/Image/RCTImageUtils.m
@@ -76,7 +76,7 @@ - (void)storeImage:(UIImage *)image withBlock:(void (^)(NSString *imageTag))bloc
{
RCTAssertParam(block);
dispatch_async(_methodQueue, ^{
NSString *imageTag = [self _storeImageData:RCTGetImageData(image.CGImage, 0.75)];
NSString *imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)];
dispatch_async(dispatch_get_main_queue(), ^{
block(imageTag);
});
@@ -197,7 +197,7 @@ - (NSString *)storeImage:(UIImage *)image
RCTLogWarn(@"RCTImageStoreManager.storeImage() is deprecated and has poor performance. Use an alternative method instead.");
__block NSString *imageTag;
dispatch_sync(_methodQueue, ^{
imageTag = [self _storeImageData:RCTGetImageData(image.CGImage, 0.75)];
imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)];
});
return imageTag;
}
@@ -76,7 +76,7 @@ RCT_EXTERN NSDictionary<NSString *, id> *__nullable RCTGetImageMetadata(NSData *
* conversion, with 1.0 being maximum quality. It has no effect for images
* using PNG compression.
*/
RCT_EXTERN NSData *__nullable RCTGetImageData(CGImageRef image, float quality);
RCT_EXTERN NSData *__nullable RCTGetImageData(UIImage *image, float quality);
/**
* This function transforms an image. `destSize` is the size of the final image,
@@ -35,6 +35,22 @@ static CGSize RCTCeilSize(CGSize size, CGFloat scale)
};
}
static CGImagePropertyOrientation CGImagePropertyOrientationFromUIImageOrientation(UIImageOrientation imageOrientation)
{
// see https://stackoverflow.com/a/6699649/496389
switch (imageOrientation) {
case UIImageOrientationUp: return kCGImagePropertyOrientationUp;
case UIImageOrientationDown: return kCGImagePropertyOrientationDown;
case UIImageOrientationLeft: return kCGImagePropertyOrientationLeft;
case UIImageOrientationRight: return kCGImagePropertyOrientationRight;
case UIImageOrientationUpMirrored: return kCGImagePropertyOrientationUpMirrored;
case UIImageOrientationDownMirrored: return kCGImagePropertyOrientationDownMirrored;
case UIImageOrientationLeftMirrored: return kCGImagePropertyOrientationLeftMirrored;
case UIImageOrientationRightMirrored: return kCGImagePropertyOrientationRightMirrored;
default: return kCGImagePropertyOrientationUp;
}
}
CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize,
CGFloat destScale, RCTResizeMode resizeMode)
{
@@ -314,20 +330,23 @@ BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,
return (__bridge_transfer id)imageProperties;
}
NSData *__nullable RCTGetImageData(CGImageRef image, float quality)
NSData *__nullable RCTGetImageData(UIImage *image, float quality)
{
NSDictionary *properties;
NSMutableDictionary *properties = [[NSMutableDictionary alloc] initWithDictionary:@{
(id)kCGImagePropertyOrientation : @(CGImagePropertyOrientationFromUIImageOrientation(image.imageOrientation))
}];
CGImageDestinationRef destination;
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
if (RCTImageHasAlpha(image)) {
CGImageRef cgImage = image.CGImage;
if (RCTImageHasAlpha(cgImage)) {
// get png data
destination = CGImageDestinationCreateWithData(imageData, kUTTypePNG, 1, NULL);
} else {
// get jpeg data
destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, NULL);
properties = @{(NSString *)kCGImageDestinationLossyCompressionQuality: @(quality)};
[properties setValue:@(quality) forKey:(id)kCGImageDestinationLossyCompressionQuality];
}
CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);
CGImageDestinationAddImage(destination, cgImage, (__bridge CFDictionaryRef)properties);
if (!CGImageDestinationFinalize(destination))
{
CFRelease(imageData);

0 comments on commit 6555f9b

Please sign in to comment.