Objective-C,iPhone iOS 6.0
下面的代码支持纵向方向正常,但是当我尝试横向时,捏缩放自动将其旋转回到笨拙的纵向模式(但在横向视图中)。
@implementation AVCapture
{
CGFloat beginGestureScale;
CGFloat effectiveScale;
}
- (id)initWithView:(UIView *)cameraView
{
......
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self rotateToInterfaceOrientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.previewLayer.frame = cameraView.frame;
[self.previewLayer setPosition:CGPointMake(CGRectGetMidX(cameraView.bounds), CGRectGetMidY(cameraView.bounds))];
[cameraView.layer addSublayer:self.previewLayer];
effectiveScale = 1.0;
......
}
- (void)rotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
CALayer *previewLayer = self.previewLayer;
switch (toInterfaceOrientation)
{
case UIDeviceOrientationLandscapeLeft:
previewLayer.transform = CATransform3DMakeRotation(M_PI+M_PI_2, 0, 0, 1); // 270 degress
break;
case UIDeviceOrientationLandscapeRight:
previewLayer.transform = CATransform3DMakeRotation(M_PI_2, 0, 0, 1); // 270 degress
break;
case UIDeviceOrientationPortraitUpsideDown:
previewLayer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1); // 270 degress
break;
default:
previewLayer.transform = CATransform3DMakeRotation(0.0, 0, 0, 1); // 270 degress
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#pragma mark Pinch to Zoom Gestures
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ( [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] )
beginGestureScale = effectiveScale;
return YES;
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer
{
if ([recognizer numberOfTouches] < 2)
return;
BOOL allTouchesAreOnThePreviewLayer = YES;
NSUInteger numTouches = [recognizer numberOfTouches], i;
for (i=0; i<numTouches; ++i)
{
CGPoint location = [recognizer locationOfTouch:i inView:m_CameraView];
CGPoint convertedLocation = [self.previewLayer convertPoint:location fromLayer:self.previewLayer.superlayer];
if (![self.previewLayer containsPoint:convertedLocation])
{
allTouchesAreOnThePreviewLayer = NO;
break;
}
}
if (allTouchesAreOnThePreviewLayer)
{
effectiveScale = beginGestureScale * recognizer.scale;
if (effectiveScale < 1.0)
effectiveScale = 1.0;
CGFloat maxScaleAndCropFactor = [[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor];
if (effectiveScale > maxScaleAndCropFactor)
effectiveScale = maxScaleAndCropFactor;
[CATransaction begin];
[CATransaction setAnimationDuration:.025];
// Scale
[self.previewLayer setAffineTransform:CGAffineTransformMakeScale(effectiveScale, effectiveScale)];
[CATransaction commit];
}
}
我似乎无法弄清楚如何维持我的变换。
答案 0 :(得分:0)
此处已回答类似问题:UIView rotates while scaling using CGAffineTransformMakeScale
在我看来,由于您手动旋转previewLayer
,因此需要相应地调整识别器,因为您使用缩放覆盖了变换。这是因为转换是绝对的,或者至少是我对它们的看法。
如何使用CGAffineTransformScale
(我在链接的问题中推荐),您可以在哪里传递previewLayer
的原始转换以及您想要的比例?
EDIT
以下是此问题的文档:https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CGAffineTransform/Reference/reference.html
在那里,您可以看到CGAffineTransformMakeScale
用于创建转换,CGAffineTransformScale
用于更改它们,我相信这就是您所需要的。
EDIT2
[UIView animateWithDuration:.25 animations:^{
self.previewLayer.transform = CGAffineTransformScale(self.previewLayer.transform, effectiveScale, effectiveScale);
}];
答案 1 :(得分:0)
解决!
找到this:
“...更改预览图层的方向不会改变图片的捕获方式。需要使用AVCaptureConnection's setVideoOrientation:
方法。”
..和this。
[captureVideoPreviewLayer.connection setVideoOrientation:self.interfaceOrientation];
所以我更换了这个:
[self rotateToInterfaceOrientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation];
用这个:
[self.previewLayer.connection setVideoOrientation:[UIDevice currentDevice].orientation];
现在一切正常,在风景模式+捏缩放。 :)