UIImagePicker wrong rotation when taking a picture - ios

I'm trying to take a picture with my iPad app but when I launch the UIImagePickerController, the camera shows the image in the wrong orientation.
Here is the code where I called the UIImagePickerController :
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0 || buttonIndex == 1) {
// Initialization
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.allowsEditing = YES;
self.imgPicker.delegate = self;
// Chosing the source
if (buttonIndex == 0) {
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; // Displayed in the good orientation
}
else {
self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imgPicker.showsCameraControls = YES;
}
// Popup pour la photo
self.imgPicker.allowsEditing = YES;
self.imgPicker.contentSizeForViewInPopover = CGSizeMake(1000, 700);
self.photoPopOver.delegate = self;
self.photoPopOver = [[UIPopoverController alloc] initWithContentViewController:self.imgPicker];
[self.photoPopOver presentPopoverFromRect:self.photoBut.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self cancel];
}
}
Things to know :
- When I set the sourceType to UIImagePickerControllerSourceTypePhotoLibrary, the view is displayed correctly
- When the picture is taken, it's displayed in the good rotation
I don't if it's useful to tell it but in the parent view controller, I have this :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
How can I fix that ? Thanks a lot !

// Solution is here to fix the Orientation of UIImage picked using UIImagePickerViewController or Camera.
Here is an example to fix the orientation issue check out here
a category is defined to fix the orientation issue in IOS. it happens when you take Picture in Portrait mode using "Camera" app in IOS device and then use it in your application via UIImagePickerViewController because default orientation of Camera is Landscape.

It sounds more like you're having issues with the camera preview having the incorrect orientation versus the image captured. Here is some code to fix your problem.

Related

iOS UIImagePickerController black screen on iPad

I'm meeting another strange problem....
I allow users to take photo. To do that, I'm using UIImagePickerController.
With iPhone, it's working, but with iPad (iOS 8, I don't know for others versions), I have a black screen preview.
This is my code :
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller usingDelegate: (id <UIImagePickerControllerDelegate, UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera] == NO) || (delegate == nil) || (controller == nil))
return NO;
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[self presentViewController:cameraUI animated:YES completion:NULL];
return YES;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"photo taken");
}
So when the user click on the button, I've the view to take the photo which appears. But the screen is black, and when I click on the button to take the photo, there is nothing.... and didFinishPickingMediaWithInfo isn't called.
(I see more topics, but I don't found any solution for this problem.)
Thanks,
Make sure you run UIKit operations on main thread. Check also if you app has permissions to use camera [in device settings].
This can also be an issue.(If it helps someone.)
Try this its solved my problem, make sure that there is a value
(Application name as string) in your info.plist > "Bundle display name".
In my case it was empty and because of that it didn't work.
If "Bundle display name" is not there in the info.plist,then add a row named "Bundle display name" and paste your appname .

How to set allowsEditing for UIImagePickerController only for videos selected from photo library in iOS?

I'm using UIImagePickerController in my applicaiton.
I'm showing the following alert in button action.
My code looks like the following in alertview delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([alertView.title isEqualToString:#"Choose"]) {
if (buttonIndex == 1) { //Camera
[self presentImagePickerControllerWithCamera:YES];
}
else if(buttonIndex == 2) { //Library
[self presentImagePickerControllerWithCamera:NO];
}
}
}
and the content of the method 'presentImagePickerControllerWithCamera' is:
- (void)presentImagePickerControllerWithCamera:(BOOL)isCamera {
CFStringRef mTypes[2] = { kUTTypeImage, kUTTypeMovie };
CFArrayRef mTypesArray = CFArrayCreate(CFAllocatorGetDefault(), (const void**)mTypes, 2, &kCFTypeArrayCallBacks);
imagePickerController.mediaTypes = (__bridge NSArray*)mTypesArray;
imagePickerController.videoMaximumDuration = 60.0f;
CFRelease(mTypesArray);
if (isCamera) { // Showing the camera (Both Camera and video)
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
imagePickerController.allowsEditing = NO;
}
else { // Showing library (Both Pictures and videos)
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentViewController:imagePickerController animated:YES completion:nil];
}
Here i need to limit the video to 1 min when user is selecting video from library, so i wrote
imagePickerController.videoMaximumDuration = 60.0f;
and
imagePickerController.allowsEditing = YES;
it's working fine. But When the user selects a picture from library i don't want editing(the square box on picture).
Is there any way to achieve it?
Any suggestions would be appreciated.
Thanks in advance.
This isn't possible with your current code.
You've assigned both the media types together. That will show you both image& video in to photo gallery. Once UIImagePickerController will show you'll not have access to it, I mean you can't know what user will select (an image or a video) before delegate get call.
So to achieve this with your case, you've to set each media type at once. And based on that media type, have to set allowsEditing property.

iOS programming. How to get picture from the phone for a phonebook app

I need your help/references/hints on how to get a pictures from 1) my Gallery in iPhone and 2)from the iPhone front camera. So that my program copies this picture to its local folder on iPhone (not just referencing to Gallery). Thanks
You might find the info on this appple developer doc useful. You use UIImagePickerController to present a modal view, as shown in the code below, from the doc above.
- (BOOL) startMediaBrowserFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// Displays saved pictures and movies, if both are available, from the
// Camera Roll album.
mediaUI.mediaTypes =
[UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeSavedPhotosAlbum];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
mediaUI.allowsEditing = NO;
mediaUI.delegate = delegate;
[controller presentModalViewController: mediaUI animated: YES];
return YES;
}
I do suggest you read through the doc above, as it is very informative but not easily paraphrasable.
Hope this helps!

iOS 7 UIImagePicker preview black screen

When i try to load camera from my code, camera preview is black. If I wait for 10-20 seconds it will show real camera preview. I found several questions and some of them suggest that running some other code in background should be the reason for this. However I don't have any code running in background.
How should I fix this?
This is my code where I run camera
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];
About 5 months ago my team discovered a memory leak with UIImageViewController in iOS7. Each instantiation slowed down the app exponentially (i.e. first alloc-init had a 1 second delay, second had a 2 second delay, third had a 5 second delay). Eventually, we were having 30-60 delays (similar to what you're experiencing).
We resolved the issue by subclassing UIImagePickerController and making it a Singleton. That way it was only ever initialized once. Now our delay is minimal and we avoid the leak. If subclassing isn't an option, try a class property in your viewController and just lazy load it like so.
-(UIImagePickerController *)imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc]init];
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
return _imagePicker;
}
Then you can just call it later like:
[self presentViewController:self.imagePicker animated:YES completion:nil];
Had this myself - it happens if something is running on the main dispatch thread - are you resizing images by any chance?
It puts the preview onto the main thread and if something is using it, you get a black screen. It's a bug and the workaround is to either take over the main thread or to disable the photo picker until the queue is free
This Should work for you:
- (void)cameraViewPickerController:(UIImagePickerController *)picker
{
[self startCameraControllerFromViewController: picker
usingDelegate: self];
}
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose movie capture
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, (NSString *) kUTTypeMovie,nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[controller presentViewController:cameraUI animated:YES completion:nil];
return YES;
}

UIImagePickerController not full screen

Since the iOS7 upgrade, I have a weird behaviour of the UIImagePickerController. In this application I am using the UIImagePickerController with a cameraOverlayView.
In iOS6 I called the UIImagePickerController using the following code:
_picker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
_picker.sourceType = UIImagePickerControllerSourceTypeCamera;
_picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
_picker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
_picker.showsCameraControls = NO;
_picker.navigationBarHidden = NO;
_picker.toolbarHidden = YES;
_picker.wantsFullScreenLayout = YES;
_overlayViewController = [[OverlayViewController alloc] init];
_overlayViewController.picker = _picker;
_overlayViewController.frameSize = self.frameSize;
_overlayViewController.delegate = self;
_picker.cameraOverlayView = _overlayViewController.view;
}
else {
_picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
_picker.delegate = self;
Where the OverlayViewController is an UIViewController, with a transparent background which draws some custom controls on screen.
But now in iOS 7 the camera is drawn through the statusbar and a black bar appears beneath the live camera view.
I can solve this by applying a CGAffineTransformMakeTranslation to the cameraViewTransform property of the UIImagePickerController, but why is this like this?
In iOS 7, by default UIViewController views take up the entire screen area including the status bar.
wantsFullScreenLayout
is deprecated and ignored. In some cases, this fix works (in the view controller class):
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)]) {
[self setEdgesForExtendedLayout:UIRectEdgeNone];
}
In other cases, it's a bit more complicated. It's late here, so see how you go with it. Helpful things to note - in a UIViewController, the following code will give the correct statusbar height on both iOS 6 and iOS 7, should it come to having to align things using CGRect math:
if (UIDeviceOrientationIsLandscape(self.interfaceOrientation)) {
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.width;
} else {
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
}
And then don't forget that in Interface Builder, there are the new "iOS 6 delta" adjustments that allow you to design for iOS 7 and then use offsets to correct for iOS 6.
Anyhow, let me know how you go.
My understanding of the issue, based on a few other SO threads and such, is that UIImagePickerController does not do what we'd expect in terms of managing the status bar via [UIViewController -prefersStatusBarHidden].
This means you either have to disable view controller status bar management entirely, via plist, or figure out a way to get UIImagePickerController to do what we want. On the assumption that you're not looking for the former, I can say I've had success in the latter by putting the picker in a wrapper controller that does what I want (but fall back to your previous code if you still need to detect/support iOS6):
#interface PickerContainer : UIViewController
#property ( nonatomic, weak ) UIImagePickerController* picker;
#end
#implementation PickerContainer
- (void) setPicker: (UIImagePickerController*) picker
{
[self addChildViewController: picker];
[picker didMoveToParentViewController: self];
self->_picker = picker;
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.picker.view.frame = self.view.bounds;
[self.view addSubview: self.picker.view];
}
// Will have no effect in ios6 -- see [-init] for that option
- (BOOL) prefersStatusBarHidden { return YES; }
- (id) init
{
if ( ! ( self = [super init] ) ) return nil;
if ( detectThatThisIsIos6() ) self.wantsFullScreenLayout = YES;
return self;
}
#end
This will work for you, scaled camera, you will have a black bar at the bottom but it will get overlayed by tool bar
https://stackoverflow.com/a/15803947

Resources