首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS相机:手动曝光时间但自动曝光?

iOS相机:手动曝光时间但自动曝光?
EN

Stack Overflow用户
提问于 2015-04-23 09:39:21
回答 3查看 7.7K关注 0票数 9

我正在使用相机视频饲料的一些图像处理,并希望优化为最快的快门速度。我知道您可以手动设置曝光持续时间和ISO

代码语言:javascript
复制
setExposureModeCustomWithDuration:ISO:completionHandler:

但这需要手动设置这两个值。是否有一种方法或巧妙的技巧可以让您手动设置曝光时间,但让ISO处理自身来尝试正确地公开图像?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-28 21:28:22

我不确定这个解决方案是否是最好的,因为我和你一样在努力解决这个问题。我所做的是听取曝光偏移量的变化,并从它们中调整ISO,直到达到可接受的曝光水平。大部分代码都是从Apple示例代码中提取的

因此,首先,您要侦听ExposureTargetOffset上的更改。添加您的类声明:

static void *ExposureTargetOffsetContext = &ExposureTargetOffsetContext;

然后,一旦正确完成设备设置:

[self addObserver:self forKeyPath:@"captureDevice.exposureTargetOffset" options:NSKeyValueObservingOptionNew context:ExposureTargetOffsetContext];

(而不是captureDevice,为设备使用属性)然后在类中实现KVO的回调:

代码语言:javascript
复制
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

if (context == ExposureTargetOffsetContext){
        float newExposureTargetOffset = [change[NSKeyValueChangeNewKey] floatValue];
        NSLog(@"Offset is : %f",newExposureTargetOffset);

        if(!self.device) return;

        CGFloat currentISO = self.device.ISO;
        CGFloat biasISO = 0;

        //Assume 0,3 as our limit to correct the ISO
        if(newExposureTargetOffset > 0.3f) //decrease ISO
            biasISO = -50;
        else if(newExposureTargetOffset < -0.3f) //increase ISO
            biasISO = 50;

        if(biasISO){
            //Normalize ISO level for the current device
            CGFloat newISO = currentISO+biasISO;
            newISO = newISO > self.device.activeFormat.maxISO? self.device.activeFormat.maxISO : newISO;
            newISO = newISO < self.device.activeFormat.minISO? self.device.activeFormat.minISO : newISO;

            NSError *error = nil;
            if ([self.device lockForConfiguration:&error]) {
                [self.device setExposureModeCustomWithDuration:AVCaptureExposureDurationCurrent ISO:newISO completionHandler:^(CMTime syncTime) {}];
                [self.device unlockForConfiguration];
            }
        }
    }
}

使用此代码,关闭速度将保持不变,ISO将被调整,以使图像不要太低或曝光过大。

当需要时,不要忘记移除观察者。希望这适合你。

干杯!

票数 7
EN

Stack Overflow用户

发布于 2018-07-20 18:06:52

@khose提供的代码示例:

private var device: AVCaptureDevice?

private var exposureTargetOffsetContext = 0

代码语言:javascript
复制
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if device == nil {
        return
    }
    if keyPath == "exposureTargetOffset" {
        let newExposureTargetOffset = change?[NSKeyValueChangeKey.newKey] as! Float
        print("Offset is : \(newExposureTargetOffset)")

        let currentISO = device?.iso
        var biasISO = 0

        //Assume 0,01 as our limit to correct the ISO
        if newExposureTargetOffset > 0.01 { //decrease ISO
            biasISO = -50
        } else if newExposureTargetOffset < -0.01 { //increase ISO
            biasISO = 50
        }

        if biasISO != Int(0) {
            //Normalize ISO level for the current device
            var newISO = currentISO! + Float(biasISO)
            newISO = newISO > (device?.activeFormat.maxISO)! ? (device?.activeFormat.maxISO)! : newISO
            newISO = newISO < (device?.activeFormat.minISO)! ? (device?.activeFormat.minISO)! : newISO

            try? device?.lockForConfiguration()
            device?.setExposureModeCustom(duration: AVCaptureDevice.currentExposureDuration, iso: newISO, completionHandler: nil)
            device?.unlockForConfiguration()
        }
    }
}

用法:

device?.addObserver(self, forKeyPath: "exposureTargetOffset", options: NSKeyValueObservingOptions.new, context: &exposureTargetOffsetContext)

票数 1
EN

Stack Overflow用户

发布于 2018-11-26 21:42:43

如果照明条件有很大的变化,接受的答案将需要很长的时间来提升/降低ISO。这里有一个例子(Swift 4),它根据曝光偏移量的比例改变ISO的值。

代码语言:javascript
复制
fileprivate var settingISO = false
@objc func exposureTargetOffsetChanged(notification: Notification) {
    guard !settingISO, self.device.exposureMode == .custom, let exposureTargetOffset = notification.userInfo?["newValue"] as? Float else {
        return
    }
    var isoChange = Float(0.0)
    let limit = Float(0.05)
    let isoChangeStep: Float
    if abs(exposureTargetOffset) > 1 {
        isoChangeStep = 500
    } else if abs(exposureTargetOffset) > 0.5 {
        isoChangeStep = 200
    } else if abs(exposureTargetOffset) > 0.2 {
        isoChangeStep = 50
    } else if abs(exposureTargetOffset) > 0.1 {
        isoChangeStep = 20
    } else {
        isoChangeStep = 5
    }

    if exposureTargetOffset > limit {
        isoChange -= isoChangeStep
    } else if exposureTargetOffset < -limit {
        isoChange += isoChangeStep
    } else {
        return
    }
    var newiso = self.device.iso + isoChange
    newiso = max(self.device.activeFormat.minISO, newiso)
    newiso = min(self.device.activeFormat.maxISO, newiso)

    guard newiso != self.device.iso, (try? self.device.lockForConfiguration()) != nil else { return }
    self.settingISO = true
    Camera.log("exposureTargetOffset=\(exposureTargetOffset), isoChange=\(isoChange), newiso=\(newiso)")

    self.device.setExposureModeCustom(duration: self.customDuration ?? AVCaptureDevice.currentExposureDuration, iso: newiso) { (_) in
        self.settingISO = false
    }
    self.device.unlockForConfiguration()
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29819515

复制
相关文章

相似问题

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