AVFoundation Image Capture - 准确捕捉用户在 UIImage 中看到的内容
Posted
技术标签:
【中文标题】AVFoundation Image Capture - 准确捕捉用户在 UIImage 中看到的内容【英文标题】:AVFoundation Image Capture - Capturing Exactly what the user sees in a UIImage 【发布时间】:2014-12-11 16:43:56 【问题描述】:我知道以前有人问过这个问题,我已经在这里尝试了这个问题的所有答案,我认为这有一些基本的东西我不明白,所以到目前为止我的努力是徒劳的。我希望有人能让我觉得自己像个白痴一样挣扎,并为我指明正确的方向。
我要做的就是使用 AVCaptureSession 捕获一个方形 UIImage 并将其显示在一个缩略图视图中,看起来与视频层中的区域完全相同。图像捕获工作正常,但是,当图像添加到我的缩略图图像视图中时,图像的顶部和底部被扩展以显示在 AvCaptureVideoPreviewLayer 中用户不可见的照片区域。
以下代码初始化我的会话,一切正常,但也许我需要在此处更改一些内容以仅捕获用户可见的部分提要:
-(void)setupFeed
self.session = [[AVCaptureSession alloc] init];
self.session.sessionPreset = AVCaptureSessionPresetPhoto;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if([self.session canAddInput:deviceInput])
[self.session addInput:deviceInput];
self.cameraPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.cameraPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
CALayer *rootLayer = [[self view] layer];
[rootLayer setMasksToBounds:YES];
CGRect frame = self.cameraPreview.frame;
[self.cameraPreviewLayer setFrame:frame];
[rootLayer insertSublayer:self.cameraPreviewLayer atIndex:0];
self.imageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.imageOutput setOutputSettings:outputSettings];
[self.session addOutput:self.imageOutput];
[self.session startRunning];
下一段代码是捕捉我的图像,这段代码也可以,裁剪到一边:
[self.imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
if(imageDataSampleBuffer != NULL)
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
self.snappedImage = [UIImage imageWithData:imageData];
[self.snappedImage crop:self.snappedImageView.layer.frame];
[self.session stopRunning];;
dispatch_async(dispatch_get_main_queue(),
^
[self presentSnappedImageOptions];
);
];
-(void)presentSnappedImageOptions
[self.imagePreview setImage: self.snappedImage];
...最后是我用来尝试将图像裁剪为与可见视频层相同的 UIImage 类别方法:
@implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)rect
rect = CGRectMake(rect.origin.x*self.scale,
rect.origin.y*self.scale,
rect.size.width*self.scale,
rect.size.height*self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *result = [UIImage imageWithCGImage:imageRef
scale:self.scale
orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
@end
我们将不胜感激任何帮助。
【问题讨论】:
【参考方案1】:我不知道您的视图是如何布局的,但也许您正在使用的裁剪矩形“self.snappedImageView.layer.frame”与预览层显示的捕获图像的区域不对应。
据我了解,预览层的框架是方形的,对,并且由于它的视频重力是纵横比填充的,我认为您可以获取图像的最大中心正方形并将其用作裁剪矩形。
你试试这个矩形怎么样
CGSize size = image.size;
CGFloat side = fminf(size.width,size.height); //just the smaller dimension
CGrect croppingRect = CGRectMake((size.width-side)/2.f,(size.height-side)/2.f,side,side);
【讨论】:
感谢您抽出宝贵时间帮助我。您的代码给了我所需的 GCRect,然后我不得不使用不同的裁剪方法来获得所需的结果。对于任何在同一件事上苦苦挣扎的人,我使用的裁剪方法是 - (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect,由 iPatel 在此处 ***.com/questions/18205672/… 发布。以上是关于AVFoundation Image Capture - 准确捕捉用户在 UIImage 中看到的内容的主要内容,如果未能解决你的问题,请参考以下文章