Issue with orientation of Image captured in landscape mode with GPUImageStillCamera - landscape

I am developing an Application where I am capturing image in landscape mode when device orientation is OFF. I am using GPUImageStillCamera for capturing image. But I'm getting issue in rotation of image. Issue is, When I capture image in landscape mode with device rotation OFF and save in gallery, then turning device rotation ON and image must rotate with device orientation. But the image is in landscape when holding device in portrait mode and If holding device in landscape, the image rotation is UpsideDown
.
Note
Image rotation works perfect when captured with device rotation ON.
Issue is only with image in landscape mode when device rotation OFF.
I have tried many solutions like this one. But didn't work for
me.
Any help will be appreciated. Thanks

I got solution to this problem . I tried to detect the accelerometer's rotation to get the rotation even when device orientation is OFF. Add CoreMotion.framerwork to your project. Then import CMMotionManager.h in your viewController. In viewDidLoad, add the following code :
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.accelerometerUpdateInterval = 1;
if ([self.motionManager isAccelerometerAvailable])
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
float xx = -accelerometerData.acceleration.x;
float yy = accelerometerData.acceleration.y;
float angle = atan2(yy, xx);
// could fire a custom shouldAutorotateToInterfaceOrientation-event here.
if(angle >= -2.25 && angle <= -0.75)
{
if(_deviceOrientation != UIInterfaceOrientationPortrait)
{
_deviceOrientation = UIInterfaceOrientationPortrait;
}
}
else if(angle >= -0.75 && angle <= 0.75)
{
if(_deviceOrientation != UIInterfaceOrientationLandscapeRight)
{
_deviceOrientation = UIInterfaceOrientationLandscapeRight;
}
}
else if(angle >= 0.75 && angle <= 2.25)
{
if(_deviceOrientation != UIInterfaceOrientationPortraitUpsideDown)
{
_deviceOrientation = UIInterfaceOrientationPortraitUpsideDown;
}
}
else if(angle <= -2.25 || angle >= 2.25)
{
if(_deviceOrientation != UIInterfaceOrientationLandscapeLeft)
{
_deviceOrientation = UIInterfaceOrientationLandscapeLeft;
}
}
});
}];
} else
NSLog(#"not active");

Related

Camera is not rotating properly in iOS8 beta for old projects

I'm working on an iOS Application which is created using older X-Code version, so it has window in MainWindow.xib.
Recently when I run this project in iOS8 Beta version, I got a problem: window is not rotating in landscape orientation. So I have added another window in MainWindow.xib. I made if condition to check OS Versions, for older iOS version I'm using previously created window but for iOS8 I'm using newly added window for landscape orientation. I have solved the problem. The entire application is working properly except the camera.
Below are screen shots.
In LandscapeMode(It's working properly):
In PortraitMode(Once camera is loaded, i have rotated it,Here other controls are rotating properly, but camera overly is not rotating properly):
Once Camera is loaded in landscape mode I have rotated device, the controls are rotating properly but the camera screen is not rotating, it is still in portrait mode.
This may be due to window in Appdelegate.
Any solution for this?
Thanks in advance.
I am having the same issue.
I was tryed to use the cameraViewTransform.
Below
#import "MyUIImagePickerController.h"
#implementation MyUIImagePickerController
bool rotateFlg = false;
UIInterfaceOrientation startupOrientation;
-(id)init{
startupOrientation = [[UIApplication sharedApplication] statusBarOrientation];
return [super init];
}
-(NSUInteger)supportedInterfaceOrientations {
// iOS 8
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
float lotate[4];
if (startupOrientation == UIInterfaceOrientationLandscapeRight || startupOrientation == UIInterfaceOrientationLandscapeLeft) {
lotate[0] = 90.0f;
lotate[1] = -90.0f;
lotate[2] = 180.0f;
lotate[3] = 0.0f;
} else {
lotate[0] = 0.0f;
lotate[1] = 180.0f;
lotate[2] = 90.0f;
lotate[3] = -90.0f;
}
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation ==UIInterfaceOrientationPortrait ){
CGAffineTransform __rotation = CGAffineTransformMakeRotation(lotate[0] * M_PI / 180.0f);
self.cameraViewTransform = __rotation;
rotateFlg = true;
}
else if(orientation == UIInterfaceOrientationPortraitUpsideDown){
CGAffineTransform __rotation = CGAffineTransformMakeRotation(lotate[1] * M_PI / 180.0f);
self.cameraViewTransform = __rotation;
rotateFlg = true;
} else if(orientation == UIInterfaceOrientationLandscapeLeft){
if (rotateFlg) {
CGAffineTransform __rotation = CGAffineTransformMakeRotation(lotate[2] * M_PI / 180.0f);
self.cameraViewTransform = __rotation;
rotateFlg = false;
}
}else if(orientation == UIInterfaceOrientationLandscapeRight){
if (rotateFlg) {
CGAffineTransform __rotation = CGAffineTransformMakeRotation(lotate[3] * M_PI / 180.0f);
self.cameraViewTransform = __rotation;
rotateFlg = false;
}
}
}
return UIInterfaceOrientationMaskAll;
}
#end
It seems to work
But the source is not beautiful ...
Have posted what I believe is a solution, over at; https://stackoverflow.com/a/26934067/782533
Looks like the same issue? Not sure if I'm supposed to link or copy/paste, so here it is anyway;
I had the same issue and after getting back to basics and creating a new project which actually worked.. I tracked it down to;
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Had forgot to call the following..
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
Hope it helps.
According to this thread on Apple Dev forums rotation in iOS8/XCode6 has some problems when using XIBs but not when using Storyboards.

Launching Image Picker in Portrait Mode on iPad

I am using the following code to launch the image picker in my iPad app (which uses Cocos2D) :
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.showsCameraControls = YES;
imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
imagePickerController.delegate = self;
imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
[self.view addSubview:imagePickerController.view];
[self presentModalViewController:imagePickerController animated:YES];
}
I want it to launch in the portrait mode all the time, but it always launches like this :
The image appears in portrait and the image picker UI is in landscape mode. But When I capture the image, it get's rotated 90 degrees clockwise.
I want the image picker UI and the taken image, both to be in portrait mode. How can I fix this ?
There are three things you need to do:
Tell the viewController that is presenting the imagePicker to only
support portrait orientation.
Tell the imagePicker to not to rotate the live camera feed.
Un-rotate captured images.
The imagePicker receives notifications of device orientation changes directly. To keep the live camera feed from rotating with the device you can stop it from receiving these notifications by telling UIDevice to endGenerating the orientation notifications after the imagePicker is presented via:
while ([currentDevice isGeneratingDeviceOrientationNotifications])
[currentDevice endGeneratingDeviceOrientationNotifications];
The reason why you put it in a loop is because the imagePicker beginsGeneratingDeviceOrientationNotifications, and then ends its when it is dismissed, bringing the notification count on a normal device from 1 to 2 back to 1.
After the imagePicker is dismissed, you can call:
while (![currentDevice isGeneratingDeviceOrientationNotifications])
[currentDevice beginGeneratingDeviceOrientationNotifications];
so that your ViewControllers can continue to receive orientation change notifications.
Unfortunately, even after turning this off, the images will still be saved with the correct imageOrientation of the camera on capture, so before you save the image or do anything with it, you'll have to remove the applied orientation transformation by manually countering it:
-(UIImage *)turnMeAround:(UIImage *)image{
CGAffineTransform transform = CGAffineTransformIdentity;
CGFloat scale = [[UIScreen mainScreen] scale]; //retina
CGSize size = CGSizeMake(image.size.width*scale,image.size.height*scale);
switch (image.imageOrientation) {
case UIImageOrientationUp:
return image;
case UIImageOrientationDown:
size = CGSizeMake(size.height,size.width);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationRight:
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
}
CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0,0,size.width,size.height), image.CGImage);
CGImageRef ref = CGBitmapContextCreateImage(context);
UIImage *upsideRight = [UIImage imageWithCGImage:ref];
CGContextRelease(context);
CGImageRelease(ref);
return upsideRight;
}
Thanks so much guys for all the help, but what worked for me is as follows :
So I found out that it was Xcode's Cocos2D template which was the culprit. It had generated the following code in the RootViewController :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//
// There are 2 ways to support auto-rotation:
// - The OpenGL / cocos2d way
// - Faster, but doesn't rotate the UIKit objects
// - The ViewController way
// - A bit slower, but the UiKit objects are placed in the right place
//
#if GAME_AUTOROTATION==kGameAutorotationNone
//
// EAGLView won't be autorotated.
// Since this method should return YES in at least 1 orientation,
// we return YES only in the Portrait orientation
//
return ( interfaceOrientation == UIInterfaceOrientationPortrait );
#elif GAME_AUTOROTATION==kGameAutorotationCCDirector
//
// EAGLView will be rotated by cocos2d
//
// Sample: Autorotate only in landscape mode
//
if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
[[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeRight];
} else if( interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
}
// Since this method should return YES in at least 1 orientation,
// we return YES only in the Portrait orientation
return ( interfaceOrientation == UIInterfaceOrientationPortrait );
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
//
// EAGLView will be rotated by the UIViewController
//
// Sample: Autorotate only in landscpe mode
//
// return YES for the supported orientations
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
#else
#error Unknown value in GAME_AUTOROTATION
#endif // GAME_AUTOROTATION
// Shold not happen
return NO;
}
In the above code I changed this :
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
To this :
return ( UIInterfaceOrientationIsPortrait( interfaceOrientation ) );
And that fixed it.

how to identify the orientation of viewController's subclass in ipad

I have one viewController class example FirstView and it has one subclass ex. secondView.
SecondView is a subclass of FirstView.Now I want to check the orientation in second view?
How to identify the secondView orientation?I checked the following method but its not working.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
When I change the orientation no method is called.
Is there any way to identify the orientation of the custom subclass?
How can I solve this issue?
[[UIApplication sharedApplication] statusBarOrientation] returns you the current device orientation.
I think you can use UIAccelerometer. You just need to implement the UIAccelerometerDelegate.
Just to get the current orientation of the view using Accelerometer you can use this code:
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// Get the current device angle
float x = [acceleration x];
float y = [acceleration y];
float angle = atan2(y, x);
if([acceleration z]>-0.84)
{
if(angle >= -2.25 && angle <= -1) // Current Orientation = Portrait
{
//Do the work
}
else if(angle >= -0.35 && angle < 0.20) //Current Orientation = Landscape Left
{
//Do the work
}
else if(angle >= 0.90 && angle <= 2.00) //Current Orientation = Portrait Upside Down
{
//Do the work
}
else if(angle <= -2.70 || angle >= 2.5) //Current Orientation = Landscape Right
{
//Do the work
}
}
}
Let me know if you need more help on this.
Hope this helps.
In you super class you should call the orientation method of its super like:
Class A {
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
}
class b inherits class a {
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
NSLog(#"Your stufs");
}
}

Manual Rotation Method Breaks with Side Switch

Currently I'm workign on a drawing app for the iPad. I need to reposition and rotate the toolbar in the app when it is put into a different orientation while keeping the the drawing area in the same place.
I found a method here for doing this. It uses the NSNotificationCenter to monitor for rotation changes. This calls a custom didRotate: method that will rotate and reposition my toolbar based on the UIDeviceOrientation.
This part works fine. However, whenever the side switch on the iPad is engaged to lock the orientation, the toolbar repositions to the location is was at launch.
For example: If I start the application in landscape left and rotate it to portrait, the toolbar will reposition to the bottom of the screen. However as soon as I engage the slide switch, it moves to the side of the screen for the landscape left orientation.
The methods I'm using for this are all below.
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)didRotate:(NSNotification *)notification {
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
UIInterfaceOrientation interfaceOrientation;
bool orientationFound = YES;
if (deviceOrientation == UIDeviceOrientationPortrait) {
interfaceOrientation = UIInterfaceOrientationPortrait;
} else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown) {
interfaceOrientation = UIInterfaceOrientationPortraitUpsideDown;
} else if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {
interfaceOrientation = UIInterfaceOrientationLandscapeRight;
} else if (deviceOrientation == UIDeviceOrientationLandscapeRight) {
interfaceOrientation = UIInterfaceOrientationLandscapeLeft;
} else {
orientationFound = NO;
}
if (orientationFound) {
[self.toolbar changeToOrientation:interfaceOrientation withDuration:.25];
[self.tutorialOverlay changeToOrientation:interfaceOrientation];
}
}
- (void)changeToOrientation:(UIInterfaceOrientation)orientation withDuration:(float)duration {
float angle;
CGPoint origin;
if (orientation == UIInterfaceOrientationPortrait) {
angle = portraitAngle;
origin = self.portraitOrigin;
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
angle = portraitUpsideDownAngle;
origin = self.portraitUpsideDownOrigin;
} else if (orientation == UIInterfaceOrientationLandscapeLeft) {
angle = landscapeLeftAngle;
origin = self.landscapeLeftOrigin;
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
angle = landscapeRightAngle;
origin = self.landscapeRightOrigin;
}
[UIView animateWithDuration:duration animations:^{
self.transform = CGAffineTransformMakeRotation(angle);
CGRect rect = self.frame;
rect.origin = origin;
self.frame = rect;
}];
}
I'd strongly recommend against using this notification-based approach. Note that the name of the notification is UIDeviceOrientationDidChangeNotification; the device orientation is not the same as the interface orientation, and it leads to lots of little issues like this. (The device orientation, for example, includes UIDeviceOrientationFaceDown, which is never associated with an interface orientation.)
I'd suggest letting your view controller automatically rotate itself; this will place the toolbar, etc, for you. You can then override - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration to put the drawing area back to the orientation you want to maintain. (You'd use similar code to your changeToOrientation method above, but for the drawing area instead, and you don't need to create your own animation block. Also, the angles would all be negated, because you're undoing the change the view controller made.)
I just answered a similar question here.
Basically just allow the interface to rotate, but rotate the view you don't want to rotate 'back' in willRotateToInterfaceOrientation:duration:.

UIScrollView Custom View rotation problem

I have a ScrollView with a Custom View. Now i have the problem with the rotation, the view has after the rotation not the correct frame pos / size.
How can i call the CustomView after rotation for a reposition and resize the frame and content?!
- (void)setupPage
{
NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
if (nimages == list.count) {
break;
}
CustomStepView *stepView = [[CustomStepView alloc] initWithFrame:CGRectZero];
stepView.tag = nimages;
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
stepView.frame = CGRectMake(cx, 0.0 , 768.0f, 926.0f);
cx += 768.0;
}
else
{
stepView.frame = CGRectMake(cx, 0.0 , 1024.0f, 670.0f);
cx += 1024.0;
}
[scrollView addSubview:stepView];
[stepView release];
}
self.pageControl.numberOfPages = nimages;
}
From what it looks like, You have a lot of subviews(Custom Views) in your ScrollView.
First of all never try to detect the orientation using UIDevice , it is not recommended by apple.
For handling rotations you have been provided with the function : "shouldAutorotateToInterfaceOrientation"
Inside this method, You can simple run a loop for detecting the subviews present inside your scrollview and then set the frame and size of each subview.
This might look something like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait)
{
for(UIView *asubview in scrollView.subviews)
{
asubview.frame = "NEW FRAME";
}
}
else
{
asubview.frame = "NEW FRAME";
}
}
Hope it helps you..although i know this has been asked long back :-)
Cheers