我想将预览层“流式传输”到我的服务器,但是,我只希望发送特定的帧。基本上,我想拍摄AVCaptureVideoPreviewLayer的快照,将其缩放到28 * 28,将其转换为强度数组,然后将其发送到我的python后端处理其余部分的套接字层。
这里的问题是AVCapturePhotoOutput的捕获功能异常缓慢。我不能重复调用该函数。更不用说它总是使相机的快门声哈哈。
另一个问题是拍摄AVCaptureVideoPreviewLayer的快照确实很困难。使用UIGraphicsBeginImageContext几乎总是返回空白/清晰图像。
帮兄弟出去,谢谢!
基本上,应该使用AVCaptureVideoDataOutputSampleBufferDelegate而不是使用AVCaptureVideoPreviewLayer来捕获帧。这是示例:
import Foundation
import UIKit
import AVFoundation
protocol CaptureManagerDelegate: class {
func processCapturedImage(image: UIImage)
}
class CaptureManager: NSObject {
internal static let shared = CaptureManager()
weak var delegate: CaptureManagerDelegate?
var session: AVCaptureSession?
override init() {
super.init()
session = AVCaptureSession()
//setup input
let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
let input = try! AVCaptureDeviceInput(device: device)
session?.addInput(input)
//setup output
let output = AVCaptureVideoDataOutput()
output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable: kCVPixelFormatType_32BGRA]
output.setSampleBufferDelegate(self, queue: DispatchQueue.main)
session?.addOutput(output)
}
func statSession() {
session?.startRunning()
}
func stopSession() {
session?.stopRunning()
}
func getImageFromSampleBuffer(sampleBuffer: CMSampleBuffer) ->UIImage? {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return nil
}
CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly)
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
let width = CVPixelBufferGetWidth(pixelBuffer)
let height = CVPixelBufferGetHeight(pixelBuffer)
let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue)
guard let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else {
return nil
}
guard let cgImage = context.makeImage() else {
return nil
}
let image = UIImage(cgImage: cgImage, scale: 1, orientation:.right)
CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
return image
}
}
extension CaptureManager: AVCaptureVideoDataOutputSampleBufferDelegate {
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
guard let outputImage = getImageFromSampleBuffer(sampleBuffer: sampleBuffer) else {
return
}
delegate?.processCapturedImage(image: outputImage)
}
}
更新:
要处理图像,您应该在所需的任何其他类中实现CaptureManagerDelegate协议的processCapturedImage方法,例如:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
CaptureManager.shared.statSession()
CaptureManager.shared.delegate = self
}
}
extension ViewController: CaptureManagerDelegate {
func processCapturedImage(image: UIImage) {
self.imageView.image = image
}
}
问题内容: 我正在使用自定义相机应用程序,本教程使用的是iOS 10弃用的AVCaptureStillImageOutput。我已经设置了相机,现在只能使用如何拍照了。 这是我有相机的全景 这是我需要帮助的地方 我已经在这里回答了如何使用AVCapturePhotoOutput,但是我不明白如何在该代码中合并该代码,因为它涉及到声明一个新类。 问题答案: 你快到了。 查看 文档以获取更多帮助。 这
问题内容: 我试图获取从Swift中的Library导入的图像的URL,以将其发送到Apple Watch,但出现两个错误。 这是我的代码: 我在 imageName和 localPath上遇到错误,因为它说: “ lastPathComponent”不可用:在NSURL上使用lastPathComponent。’stringByAppendingPathComponent’不可用:在NSURL上
我有一个方法,它应该从JSON返回不同的对象,这取决于参数中的类类型。我试着根据参数返回一个对象列表,但是我只把LinkedHashMap放入ArrayList。 我搜索了很多,但是在解决方案中,类类型的所有地方都是硬编码的。 有没有一种不用硬代码就能解决这个问题的方法? 我只想传递类类型并通过一个方法获取对象。 当我的对象有关系时,我得到这个例外 无法识别的字段"字段"(类model.orm.部
问题内容: 我对Eli Bendersky提供的示例感到有些惊讶(http://eli.thegreenplace.net/2015/the-scope-of- index-variables-in-pythons-for-loops/ ) 但是,当我想到它时,这是有道理的-Lambda捕获的是对i的引用,而不是i的价值。 因此,解决此问题的方法如下: 看来这样做的原因是,当将i提供给外部lamb
问题内容: 我一直在使用自定义相机,最近我与Swift 3一起升级到了Xcode 8 beta。 但是,我现在收到警告: iOS 10.0中不推荐使用“ AVCaptureStillImageOutput”:改用AVCapturePhotoOutput 由于这是相当新的内容,因此我没有看到太多信息。这是我当前的代码: 我尝试查看,但是我不确定如何使用它。有人知道如何使用吗?谢谢。 问题答案: 更新
这里有一个正则表达式。试试下面的字符串,我面临的问题是,在第一个组之后,每个捕获组的开头都有一个额外的空格。我需要匹配空白,但不需要捕捉它们。 正则表达式: 在上面的链接上查看它会使理解变得更简单。 这些是您可以一个接一个地粘贴到测试字符串区域中的一些字符串: 查看匹配组区域,注意在第1组之后,组之间的前1个空格被捕获。 我想做的是: 对于第一个和第二个捕获组,我希望他们检测到一个后续空间并吸收它