首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >AVFoundation轻触以聚焦反馈矩形

AVFoundation轻触以聚焦反馈矩形
EN

Stack Overflow用户
提问于 2013-03-16 20:31:08
回答 2查看 10.6K关注 0票数 22

我正在开发一个iphone应用程序,其中我直接使用AVFoundation通过摄像头捕捉视频。

我已经实现了一个特性来为用户启用tap to focus功能。

代码语言:javascript
复制
- (void) focus:(CGPoint) aPoint;
{
#if HAS_AVFF
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {        
        AVCaptureDevice *device = [captureDeviceClass defaultDeviceWithMediaType:AVMediaTypeVideo];
        if([device isFocusPointOfInterestSupported] &&
           [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
            CGRect screenRect = [[UIScreen mainScreen] bounds];
            double screenWidth = screenRect.size.width;
            double screenHeight = screenRect.size.height;
            double focus_x = aPoint.x/screenWidth;
            double focus_y = aPoint.y/screenHeight;
            if([device lockForConfiguration:nil]) {
                [device setFocusPointOfInterest:CGPointMake(focus_x,focus_y)];
                [device setFocusMode:AVCaptureFocusModeAutoFocus];
                if ([device isExposureModeSupported:AVCaptureExposureModeAutoExpose]){
                    [device setExposureMode:AVCaptureExposureModeAutoExpose];
                }
                [device unlockForConfiguration];
            }
        }
    }
#endif
}

到目前为止一切都很好,但我缺少像照片应用程序中那样的反馈矩形。有没有办法告诉AVFoundation框架显示这个反馈矩形,或者我必须自己实现这个功能?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-18 18:02:36

这是我所做的:这是一个创建正方形的类,当用户点击相机覆盖图时会显示正方形。

代码语言:javascript
复制
CameraFocusSquare.h

#import <UIKit/UIKit.h>
@interface CameraFocusSquare : UIView
@end


CameraFocusSquare.m

#import "CameraFocusSquare.h"
#import <QuartzCore/QuartzCore.h>

const float squareLength = 80.0f;
@implementation FBKCameraFocusSquare

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code

        [self setBackgroundColor:[UIColor clearColor]];
        [self.layer setBorderWidth:2.0];
        [self.layer setCornerRadius:4.0];
        [self.layer setBorderColor:[UIColor whiteColor].CGColor];

        CABasicAnimation* selectionAnimation = [CABasicAnimation
                                                animationWithKeyPath:@"borderColor"];
        selectionAnimation.toValue = (id)[UIColor blueColor].CGColor;
        selectionAnimation.repeatCount = 8;
        [self.layer addAnimation:selectionAnimation
                          forKey:@"selectionAnimation"];

    }
    return self;
}
@end

在接收点击的视图中,执行以下操作:

代码语言:javascript
复制
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchPoint = [touch locationInView:touch.view];
    [self focus:touchPoint];

    if (camFocus)
    {
        [camFocus removeFromSuperview];
    }
    if ([[touch view] isKindOfClass:[FBKVideoRecorderView class]])
    {
        camFocus = [[CameraFocusSquare alloc]initWithFrame:CGRectMake(touchPoint.x-40, touchPoint.y-40, 80, 80)];
        [camFocus setBackgroundColor:[UIColor clearColor]];
        [self addSubview:camFocus];
        [camFocus setNeedsDisplay];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.5];
        [camFocus setAlpha:0.0];
        [UIView commitAnimations];
    }
}

- (void) focus:(CGPoint) aPoint;
{
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [captureDeviceClass defaultDeviceWithMediaType:AVMediaTypeVideo];
        if([device isFocusPointOfInterestSupported] &&
           [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
            CGRect screenRect = [[UIScreen mainScreen] bounds];
            double screenWidth = screenRect.size.width;
            double screenHeight = screenRect.size.height;
            double focus_x = aPoint.x/screenWidth;
            double focus_y = aPoint.y/screenHeight;
            if([device lockForConfiguration:nil]) {
                [device setFocusPointOfInterest:CGPointMake(focus_x,focus_y)];
                [device setFocusMode:AVCaptureFocusModeAutoFocus];
                if ([device isExposureModeSupported:AVCaptureExposureModeAutoExpose]){
                    [device setExposureMode:AVCaptureExposureModeAutoExpose];
                }
                [device unlockForConfiguration];
            }
        }
    }
}
票数 36
EN

Stack Overflow用户

发布于 2020-01-10 12:52:16

这是一个基本的Swift视图,它将显示一个动画焦点方块。只需将其添加到您的相机视图,并将其连接到来自轻击手势识别器的焦点回调。

代码语言:javascript
复制
@objc func didTapToFocus(gesture: UITapGestureRecognizer) {
    let pointInViewCoordinates = gesture.location(in: gesture.view)
    let pointInCameraCoordinates = cameraView.videoPreviewLayer.captureDevicePointConverted(fromLayerPoint: pointInViewCoordinates)
    camera.focusOn(pointInCameraCoordinates: pointInCameraCoordinates)
    cameraView.showFocusBox(at: pointInViewCoordinates)
}

焦点视图:

代码语言:javascript
复制
final class CameraFocusBoxView: UIView {

    // MARK: - Instantiation

    init() {
        super.init(frame: .zero)

        backgroundColor = .clear
        layer.addSublayer(focusBoxLayer)
    }

    // MARK: - API

    /// This zooms/fades in a focus square and blinks it a few times, then slowly fades it out
    func showBox(at point: CGPoint) {
        focusBoxLayer.removeAllAnimations()
        let scaleKey = "zoom in focus box"
        let fadeInKey = "fade in focus box"
        let pulseKey = "pulse focus box"
        let fadeOutKey = "fade out focus box"
        guard focusBoxLayer.animation(forKey: scaleKey) == nil,
              focusBoxLayer.animation(forKey: fadeInKey) == nil,
              focusBoxLayer.animation(forKey: pulseKey) == nil,
              focusBoxLayer.animation(forKey: fadeOutKey) == nil
            else { return }

        CATransaction.begin()
        CATransaction.setDisableActions(true)
        focusBoxLayer.position = point
        CATransaction.commit()

        let scale = CABasicAnimation(keyPath: "transform.scale")
        scale.fromValue = 1
        scale.toValue = 0.375
        scale.duration = 0.3
        scale.isRemovedOnCompletion = false
        scale.fillMode = .forwards

        let opacityFadeIn = CABasicAnimation(keyPath: "opacity")
        opacityFadeIn.fromValue = 0
        opacityFadeIn.toValue = 1
        opacityFadeIn.duration = 0.3
        opacityFadeIn.isRemovedOnCompletion = false
        opacityFadeIn.fillMode = .forwards

        let pulsing = CABasicAnimation(keyPath: "borderColor")
        pulsing.toValue = UIColor(white: 1, alpha: 0.5).cgColor
        pulsing.repeatCount = 2
        pulsing.duration = 0.2
        pulsing.beginTime = CACurrentMediaTime() + 0.3 // wait for the fade in to occur

        let opacityFadeOut = CABasicAnimation(keyPath: "opacity")
        opacityFadeOut.fromValue = 1
        opacityFadeOut.toValue = 0
        opacityFadeOut.duration = 0.5
        opacityFadeOut.beginTime = CACurrentMediaTime() + 2 // seconds
        opacityFadeOut.isRemovedOnCompletion = false
        opacityFadeOut.fillMode = .forwards

        focusBoxLayer.add(scale, forKey: scaleKey)
        focusBoxLayer.add(opacityFadeIn, forKey: fadeInKey)
        focusBoxLayer.add(pulsing, forKey: pulseKey)
        focusBoxLayer.add(opacityFadeOut, forKey: fadeOutKey)
    }

    // MARK: - Private Properties

    private lazy var focusBoxLayer: CALayer = {
        let box = CALayer()
        box.bounds = CGRect(x: 0, y: 0, width: 200, height: 200)
        box.borderWidth = 2
        box.borderColor = UIColor.white.cgColor
        box.opacity = 0
        return box
    }()

    // MARK: - Unsupported Initializers

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15449271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档