4

I am trying forever to take a photo programmatically on iOS using Swift. However, the typical methods like:

let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
let image = renderer.image { ctx in
    view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil)

don't work. They take a photo of the everything, but not the live video (using the camera) in the background. Apparently, these methods don't include a live video from the camera in screenshots for security/permissions reasons [the live camera in the screenshot is all white], but there are workarounds. I know there is this answer: Is it possible to render AVCaptureVideoPreviewLayer in a graphics context? but it is written in all Objective-C which I can't read or use, and I'm not sure how it works. Also, there have been suggestions to use Metal, but I haven't found a Swift tutorial for that either.

Can someone please show me (in detail) some Swift code on how to take a screenshot including a photo of the live video on screen. I'm sure this will help all other Swift users too.

Thank you


Edit: Live video Code

        let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
        do {
            let input = try AVCaptureDeviceInput(device: captureDevice!)
            captureSession = AVCaptureSession()
            captureSession?.addInput(input)
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
            videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
            videoPreviewLayer?.frame = view.layer.bounds
            previewView.layer.addSublayer(videoPreviewLayer!)
            captureSession?.startRunning()

            let dataOutPut = AVCaptureVideoDataOutput()
            dataOutPut.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
            captureSession?.addOutput(dataOutPut)
        } catch {
            print(error)
        }
J.Treutlein
  • 963
  • 8
  • 23
  • Find a topic involving `AVCaptureSession`. – El Tomato Sep 15 '18 at 00:06
  • So you want to take a screenshot of the user's screen. The screen has live video playing on it. I'm assuming this is something like an AR/graphics app where graphics occur on a selfie and you want both the live video and the generated image? – noobsmcgoobs Sep 15 '18 at 00:10
  • @noobsmcgoobs That is exactly right – J.Treutlein Sep 15 '18 at 00:11
  • What kits are you using to do the AR/graphics stuff? What are you using for the live video? – noobsmcgoobs Sep 15 '18 at 00:18
  • I'm just using SpriteKit and UIKit. Then I edited my question with the live video code. – J.Treutlein Sep 15 '18 at 00:22
  • I looked at that Obj C code. It's not too hard to read. Basically, you capture the video and the graphics separately and merge them. I am not an expert in AVFoundation so all the buffers and C code got me confused. Try this one instead https://stackoverflow.com/questions/44682698/how-to-take-uiimage-of-avcapturevideopreviewlayer-instead-of-avcapturephotooutpu – noobsmcgoobs Sep 15 '18 at 00:51
  • Thanks so much!! I have got to the point where I have to merge the two images, but I don't understand how they did it in https://stackoverflow.com/questions/9012397/is-it-possible-to-render-avcapturevideopreviewlayer-in-a-graphics-context – J.Treutlein Sep 15 '18 at 04:45
  • @noobsmcgoobs Can u please explain it to me in Swift if u can, much appreciated – J.Treutlein Sep 15 '18 at 04:45
  • I am trying to apply a simple vignette filter to a live camera feed using metal. The results are pretty slow and laggy, please check this if you can tell me what is missing:https://stackoverflow.com/q/53898780/1364053 – nr5 Dec 23 '18 at 02:56
  • @nr5 I would think that any form of image rendering done for every update of a live camera would be slow. My best bet for getting it to work better would be to limit the amount of times the image is filtered, maybe every second update of the camera would work better? You could try it out and see how it goes – J.Treutlein Dec 23 '18 at 03:15

0 Answers0