Как обрезать AVCaptureVideoPreviewLayer?IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Как обрезать AVCaptureVideoPreviewLayer?

Сообщение Anonymous »

Об этом есть несколько сообщений, но все они весьма устарели. Кроме того, я использую SwiftUI и хотел бы применить решение, которое можно будет использовать в среде SwiftUI. В предисловии мне следует сказать, что я мало что знаю о UIKit.
Я пытаюсь обрезать AVCaptureVideoPreviewLayer до небольшого прямоугольника в середине экрана. Я хотел бы иметь возможность использовать его как обычное представление SwiftUI, например:

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

CameraPreview()
.frame(width: 200, height: 200)
Вот мой MRE. В этой настройке предварительный просмотр смещается в правый нижний угол экрана:

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

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
}
Но Layer.metadataOutputRectConverted(fromLayerRect: rect) не работает, если я использую маску.
Это похоже на очень распространенный случай использования, но я схожу с ума, пытаясь найти решение.

Подробнее здесь: https://stackoverflow.com/questions/786 ... eviewlayer
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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