Я пытаюсь получить мое приложение, чтобы создать UIImage правильный путь.AVCaptureSession rotation
Большая часть моего кода взяты из примеров Apple, ...
@interface CameraManager() <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) CIContext *context;
@property (nonatomic, strong) AVCaptureDevice *rearCamera;
@end
@implementation CameraManager
- (id)init {
if ((self = [super init])) {
self.context = [CIContext contextWithOptions:nil];
[self setupCamera];
[self addStillImageOutput];
}
return self;
}
- (void)setupCamera
{
self.session = [[AVCaptureSession alloc] init];
[self.session beginConfiguration];
[self.session setSessionPreset:AVCaptureSessionPresetPhoto];
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
self.rearCamera = nil;
for (AVCaptureDevice *device in devices) {
if (device.position == AVCaptureDevicePositionBack) {
self.rearCamera = device;
break;
}
}
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.rearCamera error:&error];
[self.session addInput:input];
AVCaptureVideoDataOutput *dataOutput = [[AVCaptureVideoDataOutput alloc] init];
[dataOutput setAlwaysDiscardsLateVideoFrames:YES];
NSDictionary *options = @{(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)};
[dataOutput setVideoSettings:options];
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
[self.session addOutput:dataOutput];
[self.session commitConfiguration];
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
// grab the pixel buffer
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) CMSampleBufferGetImageBuffer(sampleBuffer);
// create a CIImage from it, rotate it and zero the origin
CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) {
image = [image imageByApplyingTransform:CGAffineTransformMakeRotation(M_PI)];
}
CGPoint origin = [image extent].origin;
image = [image imageByApplyingTransform:CGAffineTransformMakeTranslation(-origin.x, -origin.y)];
// set it as the contents of the UIImageView
CGImageRef cgImage = [self.context createCGImage:image fromRect:[image extent]];
UIImage *uiImage = [UIImage imageWithCGImage:cgImage];
[[NSNotificationCenter defaultCenter] postNotificationName:@"image" object:uiImage];
CGImageRelease(cgImage);
}
- (void)addStillImageOutput
{
[self setStillImageOutput:[[AVCaptureStillImageOutput alloc] init]];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
[[self stillImageOutput] setOutputSettings:outputSettings];
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [self.stillImageOutput connections]) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
[[self session] addOutput:[self stillImageOutput]];
}
- (void)captureStillImage
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
NSLog(@"about to request a capture from: %@", [self stillImageOutput]);
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments) {
NSLog(@"attachements: %@", exifAttachments);
} else {
NSLog(@"no attachments");
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:image];
}];
}
Это моя камера менеджер код класса.
Я показываю предварительный просмотр камеры с помощью OutputSampleBufferDelegate (по разным причинам).
Я использую вывод сеанса, чтобы «сделать снимок».
Метод captureStillImage
- это бит, который я пытаюсь исправить.
Фотографии взяты с устройством в ориентации LandscapeLeft (интерфейс также является LandscapeLeft).
Предварительный просмотр всех показывает правильный путь, а данные exif также показывают ширину и высоту. (X = 3264, Y = 2448).
Но когда я показываю UIImage, он поворачивается на 90 градусов против часовой стрелки. Соотношение сторон изображения правильное (т. Е. Все выглядит нормально, круги по-прежнему являются кругами) только поворот.
Я нашел несколько категорий, которые утверждают, что исправить это.
Я также нашел несколько вопросов StackOverflow с ответами, которые также требуют исправить это.
Ничего из этого не было.
Кто-нибудь знает, как повернуть эту штуку в правильном направлении?
Обратите внимание, что вам нужно позвонить -beginGeneratingDeviceOrientationNotifications, иначе вы получите UIDeviceOrientationUnknown (0) назад. Также обратите внимание, что вы не можете просто вызвать -beginGeneratingDeviceOrientationNotifications непосредственно перед тем, как запросить ориентацию, вы должны позвонить ей некоторое время назад (например, в viewWillAppear или что-то еще). – prewett