iOS Capturing bigger image compared with camera preview mode iOS - ios

for iPhone 6 and 6+ I used following code for stretching camera on full screen.
I basically stretch camera to full screen by using cameraViewTransform. Due to this I am getting more enlarged image compared with preview mode. How can I only capture only that part that is visible in preview mode.
Refer following screen shots for more clearance
In Iphone 6 -
(in preview mode)
(captured image)
In iphone 5 -
(in preview mode)
(captured image)
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// set the aspect ratio of the camera
float heightRatio = 4.0f / 3.0f;
// calculate the height of the camera based on the screen width
float cameraHeight = screenSize.width * heightRatio;
// calculate the ratio that the camera height needs to be scaled by
float scale = screenSize.height / cameraHeight;
// move the controller to the center of the screen
self.imagePickerController.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenSize.height - cameraHeight) / 2.0);
// concatenate the scale transform
self.imagePickerController.cameraViewTransform = CGAffineTransformScale(self.imagePickerController.cameraViewTransform, scale, scale);

Related

Get camera preview position in UIImagePickerController for iPhone 12

I have a UIImagePickerController with showsCameraControls set to false. The camera preview position is being set to the center by using the cameraViewTransform property.
int cameraViewHeight = [UIScreen mainScreen].bounds.size.width * (4.0 / 3.0);
int adjustedYPosition = ([UIScreen mainScreen].bounds.size.height - cameraViewHeight) / 2;
self.imagePicker.cameraViewTransform = CGAffineTransformMakeTranslation(0, adjustedYPosition);
Normally, the position is (0,0) when showsCameraControls is false. This changes with iPhone 12, in which it keeps the same position as when showsCameraControls is true (almost centered).
Is there a way to access the position of the camera preview, in order to calculate the corresponding transformation so it can be perfectly centered?

Dynamically centering UIImagepicker viewfinder that has been scaled up to full screen

I'm making a full screen camera for the iPhone 5 and have the following code to scale the 4:3 camera to fill the entire screen, which is a 2:3 ratio. The left and right sides bleed off the screen.
I have to move the cameraView down 71 points in order for it to center with the screen. Otherwise, there's a black bar at the bottom. I'm not quite sure why. Because I don't know why this is happening, I can't figure out how to dynamically code the adjustment to accommodate the iPhone 6 and 6 Plus.
Any help is appreciated.
// get the screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// establish the height to width ratio of the camera
float heightRatio = 4.0f / 3.0f;
// calculate the height of the camera based on the screen width
float cameraHeight = screenSize.width * heightRatio;
// calculate the ratio that the camera height needs to be scaled by
float ratio = screenSize.height / cameraHeight;
//This slots the preview exactly in the middle of the screen by moving it down 71 points (for iphone 5)
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0);
self.camera.cameraViewTransform = translate;
CGAffineTransform scale = CGAffineTransformScale(translate, ratio, ratio);
self.camera.cameraViewTransform = scale;
This finally clicked in my head. Since we know that the camera will always be the same length of the screen width:
//getting the camera height by the 4:3 ratio
int cameraViewHeight = SCREEN_WIDTH * 1.333;
int adjustedYPosition = (SCREEN_HEIGHT - cameraViewHeight) / 2;
CGAffineTransform translate = CGAffineTransformMakeTranslation(0, adjustedYPosition);
self.imagePicker.cameraViewTransform = translate;

Get screen width and height only in portrait

How to get the screen width and height only in landscape orientation , i have two ipad 4 tablets and on one of them it takes me the landscape width & height , and on the other one it takes me the portrait one even if it's orientation is on lanscape
at the moment i am using this but its not working well
CGFloat width = self.view.bounds.size.width;
CGFloat height = self.view.bounds.size.height;
Use [UIScreen mainScreen].bounds you'll have the same.
Discussion
This rectangle is specified in the current coordinate
space, which takes into account any interface rotations in effect for
the device. Therefore, the value of this property may change when the
device rotates between portrait and landscape orientations.
Use [UIScreen mainScreen].nativeBounds in iOS8 only to get the portrait-locked bounds.
Discussion This rectangle is based on the device in a
portrait-up orientation. This value does not change as the device
rotates.
Swift 3
let pixelWidth = UIScreen.main.nativeBounds.width
let pixelHeight = UIScreen.main.nativeBounds.height
let pointWidth = pixelWidth / UIScreen.main.nativeScale
let pointHeight = pixelHeight / UIScreen.main.nativeScale
print ("Pixels: \(pixelWidth) x \(pixelHeight)")
print ("Points: \(pointWidth) x \(pointHeight)")
On a 6s Plus will print...
Pixels: 1080.0 x 1920.0
Points: 414.0 x 736.0

AVFoundation photo size and rotation

I'm having a nightmare time trying to correct a photo taken with AVFoundation captureStillImageAsynchronouslyFromConnection to size and orient to exactly what is shown on the screen.
I show the AVCaptureVideoPreviewLayer with this code to make sure it displays the correct way up at all rotations:
previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
previewLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
if ([[previewLayer connection] isVideoOrientationSupported])
{
[[previewLayer connection] setVideoOrientation:(AVCaptureVideoOrientation)[UIApplication sharedApplication].statusBarOrientation];
}
[self.view.layer insertSublayer:previewLayer atIndex:0];
Now when I have a returned image it needs cropping as it's much bigger than what was displayed.
I know there are loads of UIImage cropping examples, but the first hurdle I seem to have is finding the correct CGRect to use. When I simply crop to self.view.frame the image is cropped at the wrong location.
The preview is using AVLayerVideoGravityResizeAspectFill and I have my UIImageView also set to AspectFill
So how can I get the correct frame that AVFoundation is displaying on screen from the preview layer?
EDIT ----
Here's an example of the problem i'm facing. Using the front camera of an iPad Mini, the camera using the resolution 720x1280 but the display is 768x0124. The view displays this (See the dado rail at the top of the image:
Then when I take the image and display it, it looks like this:
Obviously the camera display was centred in the view, but the cropped image is taken from the top(none seen) section of the photo.
I'm working on a similar project right now and thought I might be able to help, if you haven't already figured this out.
the first hurdle I seem to have is finding the correct CGRect to use. When I simply crop to self.view.frame the image is cropped at the wrong location.
Let's say your image is 720x1280 and you want your image to be cropped to the rectangle of your display, which is a CGRect of size 768x1024. You can't just pass a rectangle of size 768x1024. First, your image isn't 768 pixels wide. Second, you need to specify the placement of that rectangle with respects to the image (i.e. by specifying the rectangle's origin point). In your example, self.view.frame is a CGRect that has an origin of (0, 0). That's why it's always cropping from the top of your image rather than from the center.
Calculating the cropping rectangle is a bit tricky because you have a few different coordinate systems.
You've got your view controller's view, which has...
...a video preview layer as a sublayer, which is displaying an aspect-filled image, but...
...the AVCaptureOutput returns a UIImage that not only has a different width/height than the video preview, but it also has a different aspect ratio.
So because your preview layer is displaying a centered and cropped preview image (i.e. aspect fill), what you basically want to find is the CGRect that:
Has the same display ratio as self.view.bounds
Has the same smaller dimension size as the smaller dimension of the UIImage (i.e. aspect fit)
Is centered in the UIImage
So something like this:
// Determine the width:height ratio of the crop rect, based on self.bounds
CGFloat widthToHeightRatio = self.bounds.size.width / self.bounds.size.height;
CGRect cropRect;
// Set the crop rect's smaller dimension to match the image's smaller dimension, and
// scale its other dimension according to the width:height ratio.
if (image.size.width < image.size.height) {
cropRect.size.width = image.size.width;
cropRect.size.height = cropRect.size.width / widthToHeightRatio;
} else {
cropRect.size.width = image.size.height * widthToHeightRatio;
cropRect.size.height = image.size.height;
}
// Center the rect in the longer dimension
if (cropRect.size.width < cropRect.size.height) {
cropRect.origin.x = 0;
cropRect.origin.y = (image.size.height - cropRect.size.height) / 2.0;
} else {
cropRect.origin.x = (image.size.width - cropRect.size.width) / 2.0;
cropRect.origin.y = 0;
}
So finally, to go back to your original example where the image is 720x1280, and you want your image to be cropped to the rectangle of your display which is 768x1024, you will end up with a CGRect of size 720x960, with an origin of x = 0, y = 1280-960/2 = 160.

Screen width and height

I want to get the width and height of the screen, with this code ...
float screenWidth = [UIScreen mainScreen].bounds.size.width;
float screenHeight = [UIScreen mainScreen].bounds.size.height;
NSLog(#"%f %f",screenWidth, screenHeight);
I get always 320 480 , but these aren't the true measures of the simulator. Now I'm testing on a retina simulator with more resolution, but i always get 320 480
I think your answer can be found here: in iPhone App How to detect the screen resolution of the device
Its the scale that interests you as well. Use CGFloat screenScale = [[UIScreen mainScreen] scale]; to find out the scale.
When positioning elements your points should always be in non-retina scale. Size of the screen for 3.5 inch is 320x480 units and 320x568 for the 4 inch screen. The pixel resolution is times two for retina screens.

Resources