IOS 17.0 — запись видео с камеры в реальном времени вместе с наложением слоевIOS

Программируем под IOS
Ответить
Anonymous
 IOS 17.0 — запись видео с камеры в реальном времени вместе с наложением слоев

Сообщение Anonymous »

Я создаю приложение для обнаружения объектов iOS, и пока все работает. Можно видеть обнаруженные объекты на отдельном слое, который добавляется поверх VideoPreviewLayer.

Код: Выделить всё

 func startVideo() {
videoCapture = VideoCapture()
videoCapture.delegate = self
videoCapture.setUp(sessionPreset: .photo) { success in
// .hd4K3840x2160 or .photo (4032x3024)  Warning: 4k may not work on all devices i.e. 2019 iPod
if success {
// Add the video preview into the UI.
if let previewLayer = self.videoCapture.previewLayer {
self.view!.layer.addSublayer(previewLayer)
self.videoCapture.previewLayer?.frame = self.view!.bounds  // resize preview layer
}

// Add the bounding box layers to the UI, on top of the video preview.
for box in self.boundingBoxViews {
box.addToLayer(self.view!.layer)
}

// Once everything is set up, we can start capturing live video.
self.videoCapture.start()
}
}
}
Однако я хочу записать изображение экрана, когда на экране появляется определенный объект. Я подумал, что довольно просто: сравнить обнаруженный класс объекта и записать UIView.
Похоже, это не работает.

Код: Выделить всё

func snapScreen() {
let bounds = UIScreen.main.bounds
//UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
//self.view!.drawHierarchy(in: bounds, afterScreenUpdates: true)

self.view!.layer.render(in: context!)
let img = UIGraphicsGetImageFromCurrentImageContext()
saveScreenImage(image: img!)
UIGraphicsEndImageContext()
}
Я запускаю это сразу после добавления ограничивающих рамок в слой предварительного просмотра. VideoPreviewLayer не захватывается. Захватывается только ограничивающийBoxLayer.
В сообщении CALayer.render(in: Context) говорится, что все слои и подслои будут отображаться в контексте.
Хорошо, поскольку это не сработало, я подумал, что videoPreviewLayer отсутствует в подслоях, поэтому я перебрал все подслои, и это, похоже, тоже не работает.

Код: Выделить всё

 func snapScreen() {
let bounds = UIScreen.main.bounds
//UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
//self.view!.drawHierarchy(in: bounds, afterScreenUpdates: true)
for layer in self.view!.layer.sublayers! {
layer.render(in: context!)
}
let img = UIGraphicsGetImageFromCurrentImageContext()
saveScreenImage(image: img!)
UIGraphicsEndImageContext()
}
Я подумал, что мне следует захватить изображение в Capture AVCapturePhotoCaptureDelegate и добавить слой поверх изображения.
  • Это не работает, либо захватывается только слой предварительного просмотра.
  • Это медленно из-за затрат на рисование изображения, и снова сохраняется только слой предварительного просмотра, а не изображение.

Код: Выделить всё

extension CameraViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let error = error {
print("error occurred : \(error.localizedDescription)")
}
DispatchQueue.main.async {
if let dataImage = photo.fileDataRepresentation() {
print(UIImage(data: dataImage)?.size as Any)
let dataProvider = CGDataProvider(data: dataImage as CFData)
let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
let image = UIImage(cgImage: cgImageRef, scale: 0.5, orientation: UIImage.Orientation.right)
let bounds = UIScreen.main.bounds
//UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
UIGraphicsPushContext(context!)
//self.view!.drawHierarchy(in: bounds, afterScreenUpdates: true)
image.draw(at: CGPoint(x: 0, y: 0))
UIGraphicsPopContext()
context?.saveGState()
self.view!.layer.render(in: context!)
context?.restoreGState()
let newImg = UIGraphicsGetImageFromCurrentImageContext()
UIImageWriteToSavedPhotosAlbum(newImg!, nil, nil, nil);
UIGraphicsEndImageContext()
// Save to camera roll

} else {
print("AVCapturePhotoCaptureDelegate Error")
}
}

}
}
Чего я хочу в идеале
Изображение

Что я получаю в CapturePhotoDelegate
Изображение

Что я получаю в SnapScreen
Изображение

Если у кого-то есть идеи, что я делаю неправильно, дайте мне знать. Единственный аспект, который мне может не хватать, это то, что в snapScreen() я не обращаюсь к буферу изображения, поскольку он уже загружен в представление. Возможно, я ошибаюсь.

Подробнее здесь: https://stackoverflow.com/questions/782 ... lay-layers
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»