React-native: imagePickerIOS - captured image has the wrong orientation

Created on 14 Jan 2017  路  4Comments  路  Source: facebook/react-native

We use GitHub Issues for bugs.

If you have a non-bug question, ask on Stack Overflow: http://stackoverflow.com/questions/tagged/react-native

If you have a feature request, post it on Product Pains: https://productpains.com/product/react-native/

--- Please use this template, and delete everything above this line before submitting your issue ---

Description

(not sure if this happens with android as we are building IOS only for now)
Picking an image from the camera roll works great but when I take a picture on an IOS device using the chooseImageFromCamera function of imagePickerIOS holding the device portrait wise the image comes back rotated counterclockwise 90 degrees. When I take a picture holding the device in landscape it comes back right side up but when I hold the device landscape in the other direction the image comes back upside down.
[FILL THIS OUT: Explain what you did, what you expected to happen, and what actually happens.]

Reproduction

import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, ImagePickerIOS, TouchableOpacity, TouchableHighlight } from 'react-native';

export default class cameraScreen extends Component {
constructor(props) {
super(props);
this.state = {
image: null,

};

}

componentDidMount() {
console.log('Ok, I am running but there is something in the code not allowing the code to render, cameraScreen')
}
chooseImageFromGallery () {
ImagePickerIOS.openSelectDialog({}, (imageUri) => {
this.setState({image: imageUri})
}, error => console.error('Error in cameraScreen.js in chooseImageFromGallery', error));
}

chooseImageFromCamera () {
ImagePickerIOS.openCameraDialog({}, (imageUri) => {
this.setState({image: imageUri})
}, error => console.error('Error in cameraScreen.js in chooseImageFromCamera', error));
}

render () {
return (

      {this.state.image? Image style={{flex:1}} source={{uri:this.state.image}} resizeMode={Image.resizeMode.contain}/>  :null}

    <View style={styles.buttonContainer}>
      <TouchableOpacity style={styles.button} onPress={this.chooseImageFromGallery.bind(this)}>
        <Text> Pick image form Camera Roll </Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.button} onPress={this.chooseImageFromCamera.bind(this)}>
        <Text> Take Picture </Text>
      </TouchableOpacity>
    </View>
  </View> 
)

}
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f9f7f5',
justifyContent: 'center',
},
buttonContainer: {
flex: 1,
flexDirection:'row',
alignItems: 'center',
justifyContent: 'center'
},
button: {
backgroundColor: 'orange',
width: 150,
height: 50,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
margin: 10
},
});
[FILL THIS OUT: Try to reproduce your bug on rnplay.org and provide a link. If you can't reproduce the bug on rnplay.org, provide a sample project.]

Solution

[FILL THIS OUT: What needs to be done to address this issue? Ideally, provide a pull request with a fix.]

Additional Information

  • React Native version: [FILL THIS OUT]
  • Platform: [FILL THIS OUT: iOS, Android, or both?]
  • Operating System: [FILL THIS OUT: MacOS, Linux, or Windows?]
Locked

Most helpful comment

@Rickapod, it may be a little too late, but if not you can fix this in didFinishPickingMediaWithInfo within RCTImagePickerManager.m. I've tested it with portrait and landscape photos taken via imagePickerIOS.openCameraDialog on iPhone 6, iOS 10.3. I found the fix here: http://stackoverflow.com/a/24770069

```

  • (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    BOOL isMovie = [mediaType isEqualToString:(NSString *)kUTTypeMovie];
    NSString *key = isMovie ? UIImagePickerControllerMediaURL : UIImagePickerControllerReferenceURL;
    NSURL *imageURL = info[key];
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    NSNumber *width = 0;
    NSNumber *height = 0;
    if (image) {
    height = @(image.size.height);
    width = @(image.size.width);
    }
    if (imageURL) {
    [self _dismissPicker:picker args:@[imageURL.absoluteString, RCTNullIfNil(height), RCTNullIfNil(width)]];
    return;
    }

// This is a newly taken image, and doesn't have a URL yet.
// We need to save it to the image store first.
UIImage *originalImage = info[UIImagePickerControllerOriginalImage];

// This fixes the image orientation <<<---
if (originalImage.imageOrientation != UIImageOrientationUp) {
UIGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale);
[originalImage drawInRect:(CGRect){{0, 0}, originalImage.size}];
originalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
// End

// WARNING: Using ImageStoreManager may cause a memory leak because the
// image isn't automatically removed from store once we're done using it.
[_bridge.imageStoreManager storeImage:originalImage withBlock:^(NSString *tempImageTag) {
[self _dismissPicker:picker args:tempImageTag ? @[tempImageTag, height, width] : nil];
}];
}

All 4 comments

@Rickapod, it may be a little too late, but if not you can fix this in didFinishPickingMediaWithInfo within RCTImagePickerManager.m. I've tested it with portrait and landscape photos taken via imagePickerIOS.openCameraDialog on iPhone 6, iOS 10.3. I found the fix here: http://stackoverflow.com/a/24770069

```

  • (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    BOOL isMovie = [mediaType isEqualToString:(NSString *)kUTTypeMovie];
    NSString *key = isMovie ? UIImagePickerControllerMediaURL : UIImagePickerControllerReferenceURL;
    NSURL *imageURL = info[key];
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    NSNumber *width = 0;
    NSNumber *height = 0;
    if (image) {
    height = @(image.size.height);
    width = @(image.size.width);
    }
    if (imageURL) {
    [self _dismissPicker:picker args:@[imageURL.absoluteString, RCTNullIfNil(height), RCTNullIfNil(width)]];
    return;
    }

// This is a newly taken image, and doesn't have a URL yet.
// We need to save it to the image store first.
UIImage *originalImage = info[UIImagePickerControllerOriginalImage];

// This fixes the image orientation <<<---
if (originalImage.imageOrientation != UIImageOrientationUp) {
UIGraphicsBeginImageContextWithOptions(originalImage.size, NO, originalImage.scale);
[originalImage drawInRect:(CGRect){{0, 0}, originalImage.size}];
originalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
// End

// WARNING: Using ImageStoreManager may cause a memory leak because the
// image isn't automatically removed from store once we're done using it.
[_bridge.imageStoreManager storeImage:originalImage withBlock:^(NSString *tempImageTag) {
[self _dismissPicker:picker args:tempImageTag ? @[tempImageTag, height, width] : nil];
}];
}

same problem for me, @jtewright fix is working.

@jtewright can you make it a pull request? I'm applying the patch right now, but for further reference it would be cool if this goes into rn core

can anyone test this on RN 0.49 and if it is causing this issue than it has to be reopened.

I tested it's on 0.44 and the issue still exists.

i tried solution provided by jtewright it's rotating the image but it's become slow.

after taking picture i am clicking on usePhoto but the button is not responding immediately.

I tested it on debug mode.

Was this page helpful?
0 / 5 - 0 ratings