2016-05-01 5 views
0

Я создаю приложение камеры с фильтром в реальном времени.Захват фото с AVFoundation в 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) 
     } 
    } 
} 

} 

Спасибо.

+0

Возможный дубликат [Как захватить изображение с AVCaptureSession в Swift? ] (http://stackoverflow.com/questions/28756363/how-to-capture-picture-with-avcapturesession-in-swift) – iYoung

+0

Вы можете сослаться на этот http://stackoverflow.com/questions/25871513/swift-take -фото-от-антенны? rq = 1 – iYoung

+0

, если вы слышите звук. вероятно, ваш код работает для Avfoundation. ваш макет представления (автозапуск) или выходы могут быть испорчены, – Shubhank

ответ

0

Если вы хотите снимать фото или видео с камеры, то вы должны использовать UIImagePickerController вместо AVFoundation. Проверьте Applce documentation для получения дополнительной информации.

Update:

См this link. В нем слишком много примеров настройки imagePickercontroller. и вы можете обратиться this и this ответ от stackobverflow.

Надеется, что это поможет :)

+0

Извините, я думаю, что uiimagepickercontroller просто позволяет вам получить доступ к собственной камере iphone. В настоящее время я пытаюсь создать полностью настроенную камеру в своем приложении. – dididaisy

+0

вы можете настроить ImagePickerController также на некотором уровне! – Lion

+0

У вас есть идея, как это сделать? – dididaisy

0

Проблемы может быть, потому что вы не имеете рамок для previewLayer.

Тип этого:

previewLayer.frame = self.view.bounds

А также явно установить видео гравитацию: (Я думаю, что это не является обязательным)

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

Привет, THX для вашего ответа. Оно работает. Но фильтр ушел. На экране нет крышки фильтра в реальном времени. Должен ли я попросить вас здесь, или мне нужно открыть новый вопрос? Спасибо! – dididaisy

+0

Добавление фильтров ПОСЛЕ того, как вы настроились и присутствуете, слой предварительного просмотра должен работать. Вероятно, они исчезли, так как они добавлены в представление, прежде чем вы покажете слой предварительного просмотра, и они находятся ниже него. Поэтому добавьте 'view.addSubview (mainGroup)' ниже 'view.addSubview (previewLayer)', и он должен работать. Если бы мой ответ был правильным для вас, тогда, пожалуйста, примите его и поддержите. (нажмите кнопку гашения с серым цветом и стрелку вверх над номером слева до ответа) – Lawrence413

Смежные вопросы