【发布时间】:2014-03-22 08:48:28
【问题描述】:
我有一个使用 AV Foundation 的照片应用程序。我已经使用占据屏幕上半部分的 AVCaptureVideoPreviewLayer 设置了一个预览层。因此,当用户尝试拍照时,他们所能看到的只是屏幕的上半部分。
这很好用,但是当用户实际拍摄照片并且我尝试将照片设置为图层的内容时,图像会失真。我做了研究并意识到我需要裁剪图像。
我想要做的就是裁剪完整的捕获图像,这样剩下的就是用户最初可以在屏幕上半部分看到的内容。
我已经能够做到这一点,但我是通过手动输入 CGRect 值来做到这一点的,但它看起来仍然不完美。必须有一种更简单的方法来做到这一点。
在过去 2 天里,我确实浏览了所有关于堆栈溢出的关于裁剪图像的帖子,但没有任何效果。
必须有一种方法以编程方式裁剪捕获的图像,以便最终图像与最初在预览层中看到的完全一致。
这是我的 viewDidLoad 实现:
- (void)viewDidLoad
{
[super viewDidLoad];
AVCaptureSession *session =[[AVCaptureSession alloc]init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = [[NSError alloc]init];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
if([session canAddInput:deviceInput])
[session addInput:deviceInput];
CALayer *rootLayer = [[self view]layer];
[rootLayer setMasksToBounds:YES];
_previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session];
[_previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height/2)];
[_previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[rootLayer insertSublayer:_previewLayer atIndex:0];
_stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
[session addOutput:_stillImageOutput];
[session startRunning];
}
这是当用户按下按钮拍摄照片时运行的代码:
-(IBAction)stillImageCapture {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in _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: %@", _stillImageOutput);
[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if(imageDataSampleBuffer) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc]initWithData:imageData];
CALayer *subLayer = [CALayer layer];
subLayer.frame = _previewLayer.frame;
image = [self rotate:image andOrientation:image.imageOrientation];
//Below is the crop that is sort of working for me, but as you can see I am manually entering in values and just guessing and it still does not look perfect.
CGRect cropRect = CGRectMake(0, 650, 3000, 2000);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
subLayer.contents = (id)[UIImage imageWithCGImage:imageRef].CGImage;
subLayer.frame = _previewLayer.frame;
[_previewLayer addSublayer:subLayer];
}
}];
}
【问题讨论】:
标签: ios objective-c avfoundation calayer avcapturesession