#ios #swift #augmented-reality #realitykit
#iOS #swift #дополненная реальность #realitykit
Вопрос:
У меня есть приложение дополненной реальности, созданное с использованием RealityKit в Swift 5. Я хотел бы получить необработанное изображение базовой сцены (без виртуальных объектов). Я запускаю приведенный ниже код, однако он никогда не делает никаких снимков, но выдает сообщение об ошибке с надписью «Невозможно записать». Документация по этому вопросу несколько скудна, поэтому мы будем признательны за любую помощь.
import Foundation
import AVFoundation
class CapturePhoto: NSObject, AVCapturePhotoCaptureDelegate{
var capture = AVCapturePhotoOutput()
var availableCameraSettings: Array<AVCapturePhotoSettings> = []
var session = AVCaptureSession()
let prompt = Prompt()
override init(){
super.init()
createSettings()
configOutput()
configSession()
startSesssion()
// do any other config here
}
func configOutput(){
capture.isHighResolutionCaptureEnabled = true
capture.setPreparedPhotoSettingsArray( availableCameraSettings, completionHandler: nil )
}
func configSession(){
session.stopRunning()
session.beginConfiguration()
session.sessionPreset = .photo
let input = try? AVCaptureDeviceInput( device: getDevice() )
if( session.canAddOutput( capture ) ){
session.addOutput( capture )
}
if ( session.canAddInput( input! ) ){
session.addInput( input! )
}
session.commitConfiguration()
}
func startSesssion(){
session.startRunning()
}
func stopSession(){
session.stopRunning()
}
func getDevice() -> AVCaptureDevice{
if let device = AVCaptureDevice.default(.builtInWideAngleCamera,
for: .video, position: .back) {
return device
} else {
fatalError("Missing expected back camera device.")
}
}
func getBestSettings() -> AVCapturePhotoSettings{
return AVCapturePhotoSettings( /* rawPixelFormatType: 0 */ )
}
func createSettings(){
let settings = getBestSettings()
settings.flashMode = .on
if #available(iOS 14.1, *) {
settings.isAutoContentAwareDistortionCorrectionEnabled = false
}
settings.isAutoRedEyeReductionEnabled = false
settings.isCameraCalibrationDataDeliveryEnabled = false
settings.isHighResolutionPhotoEnabled = false
settings.isPortraitEffectsMatteDeliveryEnabled = false
availableCameraSettings.append( settings )
let ditto = AVCapturePhotoSettings( from: settings )
ditto.flashMode = .off
availableCameraSettings.append( ditto )
}
func captureImage()
{
for setting in availableCameraSettings{
let settings = AVCapturePhotoSettings( from: setting )
capture.capturePhoto(with: settings, delegate: self )
}
}
func photoOutput(_ output: AVCapturePhotoOutput,
didFinishProcessingPhoto photo: AVCapturePhoto,
error: Error?)
{
if error != nil {
print( error!.localizedDescription )
prompt.prompt ( Info( error!.localizedDescription, 0 ) )
} else{
print( photo.timestamp )
print ( ( photo.isRawPhoto ? " Raw" : " Not raw" ) "n" )
DispatchQueue.global( qos: .background ).async {
AudioServicesPlaySystemSound( 1108 )
}
}
}
}
Комментарии:
1. Это практически невозможно, как указано в приведенном ниже ответе, если только вы не приостановите выполнение ARSession. Теперь я использую вместо этого изображение из ARSession.
Ответ №1:
Насколько мне известно, вы не можете начать сеанс захвата, так как ARSession удерживается на камере (камерах), поэтому вы не сможете захватить изображение именно так, как вы хотите.
Однако, чтобы получить сцену без всех 3D-объектов, вы можете получить изображение, которое в данный момент использует ARSession, следующим образом: self.arView.session.currentFrame?.capturedImage
Где self.arView
находится текущий ARView.
capturedImage — это CVPixelBuffer, и есть много способов преобразовать его в UIImage или что-то еще, что вы можете захотеть, что-то вроде этого:
if let img = self.arView.session.currentFrame?.capturedImage {
let ciimg = CIImage(cvImageBuffer: img)
let finImage = UIImage(ciImage: ciimg)
}
Возможно, вам также придется настроить изображение для ориентации устройства.
Оригинальный ответ:
Если вам нужна сцена с 3D-объектами view.snapshot(:)
https://developer.apple.com/documentation/realitykit/arview/3255319-snapshot
Комментарии:
1. Привет, Макс. Спасибо за быстрый ответ. Я знаю об этой функции, однако, насколько я понимаю, она будет захватывать то, что находится на экране (с видимой AR-сценой). Мне нужно захватить основную сцену без каких-либо виртуальных объектов в raw и, помимо прочего, управлять вспышкой.
2. Просто откорректировал мой ответ! надеюсь, это больше то, что вы ищете
3. Спасибо, теперь я использую ARSession для этого. Работает хорошо