尺寸为一个像素一个像素的相机进纸

时间:2017-05-28 19:12:00

标签: swift avfoundation

这是一个相当奇怪的请求,但我希望构建一个具有实时摄像头馈送占据整个屏幕的应用程序。但是,它不是显示正常分辨率,而是一种颜色。特别是,我想采用通常在屏幕上的中间像素的颜色,并使其占据整个屏幕。它需要现场和快速完成。

我尝试创建一个将capturesession保存为uiimage的函数,然后从中获取像素数据,但事实证明它很慢。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

假设您有AVCaptureSession设置。您需要设置AVCaptureVideoDataOutput,然后设置其样本缓冲区委托。委托类应覆盖func captureOutput(AVCaptureOutput!, CMSampleBuffer!, AVCaptureConnection!)。在此功能中,您可以访问像素缓冲区以对中心点进行采样。你可以这样做。我已经把中心点的实际采样留给了你。

class MyClass : NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {

    func addVideoOutput() {
        // Add video data output.
        if session.canAddOutput(videoDataOutput)
        {
            videoDataOutput.setSampleBufferDelegate(self, queue: sessionQueue)
            videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as NSString:Int(kCVPixelFormatType_32BGRA)]

            videoDataOutput.alwaysDiscardsLateVideoFrames = true
            session.addOutput(videoDataOutput)
        }
    }

    // AVCaptureVideoDataOutputSampleBufferDelegate
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        if let buffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
            process(pixelBuffer: buffer)
        }
    }
    func process(pixelBuffer: CVPixelBuffer) {
        let sourceRowBytes = CVPixelBufferGetBytesPerRow( pixelBuffer );
        let width = CVPixelBufferGetWidth( pixelBuffer );
        let height = CVPixelBufferGetHeight( pixelBuffer );

        let rt = CVPixelBufferLockBaseAddress( pixelBuffer, .readOnly );
        if (rt == kCVReturnSuccess) {
            ... 
            Do your processing of the pixeldata here
            ...
            CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
        }
    }

    private let session = AVCaptureSession()
    private let sessionQueue = DispatchQueue(label: "session queue", attributes: [], target: nil) // Communicate with the session     
    private let videoDataOutput = AVCaptureVideoDataOutput()
}