Я пытаюсь обрезать AVCaptureVideoPreviewLayer до небольшого прямоугольника в середине экрана. Я хотел бы иметь возможность использовать его как обычное представление SwiftUI, например:
Код: Выделить всё
CameraPreview()
.frame(width: 200, height: 200)
Код: Выделить всё
class CameraViewController: UIViewController {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
captureSession = AVCaptureSession()
captureSession.sessionPreset = .photo
guard let backCamera = AVCaptureDevice.default(for: .video) else { return }
do {
let input = try AVCaptureDeviceInput(device: backCamera)
if captureSession.canAddInput(input) {
captureSession.addInput(input)
}
} catch {
print("Error: \(error.localizedDescription)")
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = .resizeAspect
previewLayer.frame = view.layer.bounds
view.layer.addSublayer(at: previewLayer)
captureSession.startRunning()
}
}
struct CameraView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> CameraViewController {
return CameraViewController()
}
func updateUIViewController(_ uiViewController: CameraViewController, context: Context) {}
}
Код: Выделить всё
CameraView()
.mask(
Rectangle()
.ignoresSafeArea()
.opacity(0.0)
.overlay(
RoundedRectangle(cornerRadius: 25)
.frame(width: 100, height: 100)
.opacity(1)
)
)
Кроме того, мне нужна возможность делать фотографии в этом поле. Я могу вручную обрезать снятую фотографию, используя:
Код: Выделить всё
func crop(toPreviewLayer layer: AVCaptureVideoPreviewLayer, withRect rect: CGRect) -> UIImage {
let outputRect = layer.metadataOutputRectConverted(fromLayerRect: rect)
var cgImage = self.cgImage!
let width = CGFloat(cgImage.width)
let height = CGFloat(cgImage.height)
let cropRect = CGRect(
x: outputRect.origin.x * width,
y: outputRect.origin.y * height,
width: outputRect.size.width * width,
height: outputRect.size.height * height)
cgImage = cgImage.cropping(to: cropRect)!
let croppedUIImage = UIImage(
cgImage: cgImage,
scale: self.scale,
orientation: self.imageOrientation
)
return croppedUIImage
}
Это похоже на очень распространенный случай использования, но я схожу с ума, пытаясь найти решение.
Подробнее здесь: https://stackoverflow.com/questions/786 ... eviewlayer