【问题标题】:Capture photo with AVFoundation in Swift在 Swift 中使用 AVFoundation 拍摄照片
【发布时间】:2016-08-26 02:29:49
【问题描述】:

我正在 swift 中构建一个实时滤镜相机应用程序。

我正在从 AVCaptureVideoDataOutput() 更改为 AVCaptureStillImageOutput() 以执行捕获照片功能。更改后,打开应用程序时没有预览视图。

抓拍功能正常,点击主组区可以听到抓拍声“咔”。这里没有风景。

这是我的完整代码

import Foundation
import UIKit
import AVFoundation
import CoreMedia

let CIHueAdjust = "CIHueAdjust"
let CIHueAdjustFilter = CIFilter(name: "CIHueAdjust", withInputParameters: ["inputAngle" : 1.24])

let Filters = [CIHueAdjust: CIHueAdjustFilter]

let FilterNames = [String](Filters.keys).sort()

class LiveCamViewController :       UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
let mainGroup = UIStackView()
let imageView = UIImageView(frame: CGRectZero)
let filtersControl = UISegmentedControl(items: FilterNames)
var videoOutput = AVCaptureStillImageOutput()

override func viewDidLoad()
{
    super.viewDidLoad()

    view.addSubview(mainGroup)
    mainGroup.axis = UILayoutConstraintAxis.Vertical
    mainGroup.distribution = UIStackViewDistribution.Fill

    mainGroup.addArrangedSubview(imageView)
    mainGroup.addArrangedSubview(filtersControl)
    mainGroup.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(LiveCamViewController.saveToCamera(_:))))

    imageView.contentMode = UIViewContentMode.ScaleAspectFit

    filtersControl.selectedSegmentIndex = 0

    let captureSession = AVCaptureSession()
    captureSession.sessionPreset = AVCaptureSessionPresetPhoto

    let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    do
    {
        let input = try AVCaptureDeviceInput(device: backCamera)

        captureSession.addInput(input)
    }
    catch
    {
        print("can't access camera")
        return
    }

    //get captureOutput invoked
    let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    view.layer.addSublayer(previewLayer)

    videoOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

    if captureSession.canAddOutput(videoOutput)
    {
        captureSession.addOutput(videoOutput)
    }

    captureSession.startRunning()
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
{
    guard let filter = Filters[FilterNames[filtersControl.selectedSegmentIndex]] else
    {
        return
    }

    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)

    filter!.setValue(cameraImage, forKey: kCIInputImageKey)

    let filteredImage = UIImage(CIImage: filter!.valueForKey(kCIOutputImageKey) as! CIImage!)
    let fixedImage = correctlyOrientedImage(filteredImage)

    dispatch_async(dispatch_get_main_queue())
    {
        self.imageView.image = fixedImage
    }

}

func correctlyOrientedImage(image: UIImage) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
    image.drawInRect(CGRectMake(0, 0, image.size.width, image.size.height))
    let normalizedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    let imageRef: CGImageRef = normalizedImage.CGImage!
    let rotatedImage: UIImage = UIImage(CGImage: imageRef, scale: 1.0, orientation: .Right)

    return rotatedImage
}

override func viewDidLayoutSubviews()
{
    mainGroup.frame = CGRect(x: 37, y: 115, width: 301, height: 481)
}

func saveToCamera(sender: UITapGestureRecognizer) {

    videoOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

    if let videoConnection = videoOutput.connectionWithMediaType(AVMediaTypeVideo) {
        videoOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {
            (imageDataSampleBuffer, error) -> Void in
            let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
            UIImageWriteToSavedPhotosAlbum(UIImage(data: imageData)!, nil, nil, nil)
        }
    }
}

}

谢谢。

【问题讨论】:

标签: ios swift camera avfoundation


【解决方案1】:

问题可能是因为您没有previewLayer 的框架。

键入:

previewLayer.frame = self.view.bounds

并且还明确设置了视频重力:(我认为这是可选的)

previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill // Or choose some other option if you prefer

【讨论】:

  • 您好,谢谢您的回答。有用。但是过滤器不见了..屏幕上没有实时过滤器盖..我应该在这里问你,还是应该打开一个新问题?谢谢你!
  • 在设置和呈现预览层之后添加过滤器应该可以工作。它们可能已经消失了,因为它们在您显示预览层之前被添加到视图中并且它们在它下方。所以在view.addSubview(previewLayer)下面添加view.addSubview(mainGroup),它应该可以工作。如果我的回答对你来说是正确的,那么请接受并投票。 (按灰色的勾号按钮和答案左侧数字上方的向上箭头)
【解决方案2】:

如果您想从相机拍摄照片或视频,则应使用UIImagePickerController 而不是AVFoundation。查看Applce documentation 了解更多信息。

更新:

请参阅this link。它有太多自定义imagePickercontroller 的例子。你可以参考this 和thisstackobverflow的答案。

希望这会有所帮助:)

【讨论】:

  • 对不起,我认为 uiimagepickercontroller 只是允许你访问 iphone 自己的相机。目前我正在尝试在我的应用程序中构建一个完全定制的相机。
  • 你也可以在一定程度上自定义imagePickerController!!
  • 你知道怎么做吗?
猜你喜欢
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
相关资源
最近更新 更多