Fix photo orientation from ImagePickerIOS
Summary: Original PR: https://github.com/facebook/react-native/pull/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 https://github.com/facebook/react-native/pull/15060 Differential Revision: D5487595 Pulled By: shergin fbshipit-source-id: ce1a47f4d5ba33e03070f318f3d6a8dd0df5ab88
This commit is contained in:
parent
eec58237ce
commit
6555f9bee8
|
@ -76,7 +76,7 @@ RCT_EXPORT_MODULE()
|
||||||
{
|
{
|
||||||
RCTAssertParam(block);
|
RCTAssertParam(block);
|
||||||
dispatch_async(_methodQueue, ^{
|
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(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
block(imageTag);
|
block(imageTag);
|
||||||
});
|
});
|
||||||
|
@ -197,7 +197,7 @@ RCT_EXPORT_METHOD(addImageFromBase64:(NSString *)base64String
|
||||||
RCTLogWarn(@"RCTImageStoreManager.storeImage() is deprecated and has poor performance. Use an alternative method instead.");
|
RCTLogWarn(@"RCTImageStoreManager.storeImage() is deprecated and has poor performance. Use an alternative method instead.");
|
||||||
__block NSString *imageTag;
|
__block NSString *imageTag;
|
||||||
dispatch_sync(_methodQueue, ^{
|
dispatch_sync(_methodQueue, ^{
|
||||||
imageTag = [self _storeImageData:RCTGetImageData(image.CGImage, 0.75)];
|
imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)];
|
||||||
});
|
});
|
||||||
return imageTag;
|
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
|
* conversion, with 1.0 being maximum quality. It has no effect for images
|
||||||
* using PNG compression.
|
* 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,
|
* 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,
|
CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize,
|
||||||
CGFloat destScale, RCTResizeMode resizeMode)
|
CGFloat destScale, RCTResizeMode resizeMode)
|
||||||
{
|
{
|
||||||
|
@ -314,20 +330,23 @@ NSDictionary<NSString *, id> *__nullable RCTGetImageMetadata(NSData *data)
|
||||||
return (__bridge_transfer id)imageProperties;
|
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;
|
CGImageDestinationRef destination;
|
||||||
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
|
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
|
||||||
if (RCTImageHasAlpha(image)) {
|
CGImageRef cgImage = image.CGImage;
|
||||||
|
if (RCTImageHasAlpha(cgImage)) {
|
||||||
// get png data
|
// get png data
|
||||||
destination = CGImageDestinationCreateWithData(imageData, kUTTypePNG, 1, NULL);
|
destination = CGImageDestinationCreateWithData(imageData, kUTTypePNG, 1, NULL);
|
||||||
} else {
|
} else {
|
||||||
// get jpeg data
|
// get jpeg data
|
||||||
destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, NULL);
|
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))
|
if (!CGImageDestinationFinalize(destination))
|
||||||
{
|
{
|
||||||
CFRelease(imageData);
|
CFRelease(imageData);
|
||||||
|
|
Loading…
Reference in New Issue