Eugene Trapeznikov Eugene Trapeznikov - 11 months ago 72
iOS Question

Custom camera iOS

I got an app, where i tried to implement custom camera. This is source code:

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];

captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[self.vImagePreview.layer addSublayer:captureVideoPreviewLayer];

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//device.position ;
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
[session addInput:input];
[session startRunning];

stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];

[session addOutput:stillImageOutput];

Then i tried to create photo and send it to other view controller:

-(IBAction) captureNow
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImageOutput.connections)
for (AVCaptureInputPort *port in [connection inputPorts])
if ([[port mediaType] isEqual:AVMediaTypeVideo] )
videoConnection = connection;
if (videoConnection) { break; }

//NSLog(@"about to request a capture from: %@", stillImageOutput);

AcceptingPhotoViewController *photo = [[AcceptingPhotoViewController alloc] initWithNibName:@"AcceptingPhotoViewController" bundle:nil];

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];

photo.image = [[UIImage alloc] init ];
photo.image = image;
photo.photoFromCamera = YES;

[self.navigationController pushViewController:photo animated:NO];

But in my target class this image is rotating to the left on 90 degrees:
enter image description here

I tried to rotate it back:

float newSide = MAX([image size].width, [image size].height);
CGSize size = CGSizeMake(newSide, newSide);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, newSide/2, newSide/2);
CGContextRotateCTM(ctx, 1.57079633);
CGContextDrawImage(UIGraphicsGetCurrentContext(),CGRectMake(-[image size].width/2,-[image size].height/2,size.width, size.height),image.CGImage);
UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
image = i;

My image rotated on the right, but it display mirrored and stretch.

Any help? Can i rotate in other way, or maybe i should take photo not like this?

Answer Source

I found solve of this problem:

I rotate and transform image in this way

UIView* rotatedViewBox = [[UIView alloc] initWithFrame: CGRectMake(0, 0, image.size.width, image.size.height)];
                    float angleRadians = 90 * ((float)M_PI / 180.0f);
                    CGAffineTransform t = CGAffineTransformMakeRotation(angleRadians);
                    rotatedViewBox.transform = t;
                    CGSize rotatedSize = rotatedViewBox.frame.size;

                CGContextRef bitmap = UIGraphicsGetCurrentContext();
                CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
                CGContextRotateCTM(bitmap, angleRadians);

                CGContextScaleCTM(bitmap, 1.0, -1.0);
                CGContextDrawImage(bitmap, CGRectMake(-image.size.width / 2, -image.size.height / 2, image.size.width, image.size.height), [image CGImage]);

                UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
                image = newImage;

                CGSize newSize = CGSizeMake(image.size.height, image.size.width);

                // Tell the old image to draw in this new context, with the desired
                // new size
                [image drawInRect:CGRectMake(0,0,image.size.height,image.size.width)];

                // Get the new image from the context
                UIImage* newImage2 = UIGraphicsGetImageFromCurrentImageContext();

                // End the context

                image = newImage2;