Ios 如何在Swift中更改视频视图的大小

Ios 如何在Swift中更改视频视图的大小,ios,swift,xcode,video,Ios,Swift,Xcode,Video,我是Swift的新手,我正在尝试实施一些项目。我从中得到了这个代码,它工作得很好 当你点击应用程序时,它会在iPhone屏幕上启动一个视频,并使用'TesseractOCR'检测字母和字符 问题是视频覆盖了整个屏幕,我无法添加任何按钮。如果我添加一个按钮,它将消失在视频下 我试图添加session.sessionPreset=.photo从上到下裁剪视频,但没有成功。我还尝试添加preview.sessionPreset=.photo,但也没有成功 注意:Main.storyboard为空 代

我是Swift的新手,我正在尝试实施一些项目。我从中得到了这个代码,它工作得很好

当你点击应用程序时,它会在iPhone屏幕上启动一个视频,并使用
'TesseractOCR'
检测字母和字符

问题是视频覆盖了整个屏幕,我无法添加任何按钮。如果我添加一个按钮,它将消失在视频下

我试图添加
session.sessionPreset=.photo
从上到下裁剪视频,但没有成功。我还尝试添加
preview.sessionPreset=.photo
,但也没有成功

注意:
Main.storyboard
为空

代码如下:

import AVFoundation
import UIKit
import Vision
import TesseractOCR


class ViewController: UIViewController, G8TesseractDelegate  {




    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tesseract?.pageSegmentationMode = .sparseText
        // Recognize only these characters


//        tesseract?.charWhitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890()-+*!/?.,@#$%&"
        tesseract?.charWhitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"


        if isAuthorized() {
            configureTextDetection()
            configureCamera()
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    private func configureTextDetection() {
        textDetectionRequest = VNDetectTextRectanglesRequest(completionHandler: handleDetection)
        textDetectionRequest?.reportCharacterBoxes = true
    }
    private func configureCamera() {
        preview.session = session

        let cameraDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)
        var cameraDevice: AVCaptureDevice?
        for device in cameraDevices.devices {
            if device.position == .back {
                cameraDevice = device
                break
            }
        }
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: cameraDevice!)
            if session.canAddInput(captureDeviceInput) {
                session.addInput(captureDeviceInput)
            }
        }
        catch {
            print("Error occured \(error)")
            return
        }
        session.sessionPreset = .photo   // It was .high
        let videoDataOutput = AVCaptureVideoDataOutput()
        videoDataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "Buffer Queue", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil))
        if session.canAddOutput(videoDataOutput) {
            session.addOutput(videoDataOutput)
        }
        preview.videoPreviewLayer.videoGravity = .resize
        session.startRunning()
    }
    private func handleDetection(request: VNRequest, error: Error?) {

        guard let detectionResults = request.results else {
            print("No detection results")
            return
        }
        let textResults = detectionResults.map() {
            return $0 as? VNTextObservation
        }
        if textResults.isEmpty {
            return
        }
        textObservations = textResults as! [VNTextObservation]
        DispatchQueue.main.async {

            guard let sublayers = self.view.layer.sublayers else {
                return
            }
            for layer in sublayers[1...] {
                if (layer as? CATextLayer) == nil {
                    layer.removeFromSuperlayer()
                }
            }
            let viewWidth = self.view.frame.size.width
            let viewHeight = self.view.frame.size.height
            for result in textResults {

                if let textResult = result {

                    let layer = CALayer()
                    var rect = textResult.boundingBox
                    rect.origin.x *= viewWidth
                    rect.size.height *= viewHeight
                    rect.origin.y = ((1 - rect.origin.y) * viewHeight) - rect.size.height
                    rect.size.width *= viewWidth

                    layer.frame = rect
                    layer.borderWidth = 2
                    layer.borderColor = UIColor.red.cgColor
                    self.view.layer.addSublayer(layer)
                }
            }
        }
    }

    private var preview: PreviewView {
        return view as! PreviewView
    }
//    private var cameraView: CameraView {
//        return view as! CameraView
//    }
    private func isAuthorized() -> Bool {
        let authorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        switch authorizationStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: AVMediaType.video,
                                          completionHandler: { (granted:Bool) -> Void in
                                            if granted {
                                                DispatchQueue.main.async {
                                                    self.configureTextDetection()
                                                    self.configureCamera()
                                                }
                                            }
            })
            return true
        case .authorized:
            return true
        case .denied, .restricted: return false
        }
    }
    private var textDetectionRequest: VNDetectTextRectanglesRequest?
    private let session = AVCaptureSession()
    private var textObservations = [VNTextObservation]()
    private var tesseract = G8Tesseract(language: "eng", engineMode: .tesseractOnly)
    private var font = CTFontCreateWithName("Helvetica" as CFString, 18, nil)
}

extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
    // MARK: - Camera Delegate and Setup
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return
        }
        var imageRequestOptions = [VNImageOption: Any]()
        if let cameraData = CMGetAttachment(sampleBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil) {
            imageRequestOptions[.cameraIntrinsics] = cameraData
        }
        let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: CGImagePropertyOrientation(rawValue: 6)!, options: imageRequestOptions)
        do {
            try imageRequestHandler.perform([textDetectionRequest!])
        }
        catch {
            print("Error occured \(error)")
        }
        var ciImage = CIImage(cvPixelBuffer: pixelBuffer)
        let transform = ciImage.orientationTransform(for: CGImagePropertyOrientation(rawValue: 6)!)
        ciImage = ciImage.transformed(by: transform)
        let size = ciImage.extent.size
        var recognizedTextPositionTuples = [(rect: CGRect, text: String)]()
        for textObservation in textObservations {
            guard let rects = textObservation.characterBoxes else {
                continue
            }
            var xMin = CGFloat.greatestFiniteMagnitude
            var xMax: CGFloat = 0
            var yMin = CGFloat.greatestFiniteMagnitude
            var yMax: CGFloat = 0
            for rect in rects {

                xMin = min(xMin, rect.bottomLeft.x)
                xMax = max(xMax, rect.bottomRight.x)
                yMin = min(yMin, rect.bottomRight.y)
                yMax = max(yMax, rect.topRight.y)
            }
            let imageRect = CGRect(x: xMin * size.width, y: yMin * size.height, width: (xMax - xMin) * size.width, height: (yMax - yMin) * size.height)
            let context = CIContext(options: nil)
            guard let cgImage = context.createCGImage(ciImage, from: imageRect) else {
                continue
            }
            let uiImage = UIImage(cgImage: cgImage)
            tesseract?.image = uiImage
            tesseract?.recognize()
            guard var text = tesseract?.recognizedText else {
                continue
            }
            text = text.trimmingCharacters(in: CharacterSet.newlines)
            if !text.isEmpty {
                let x = xMin
                let y = 1 - yMax
                let width = xMax - xMin
                let height = yMax - yMin
                recognizedTextPositionTuples.append((rect: CGRect(x: x, y: y, width: width, height: height), text: text))



            }
        }
        textObservations.removeAll()
        DispatchQueue.main.async {
            let viewWidth = self.view.frame.size.width
            let viewHeight = self.view.frame.size.height
            guard let sublayers = self.view.layer.sublayers else {
                return
            }
            for layer in sublayers[1...] {

                if let _ = layer as? CATextLayer {
                    layer.removeFromSuperlayer()
                }
            }
            for tuple in recognizedTextPositionTuples {
                let textLayer = CATextLayer()
                textLayer.backgroundColor = UIColor.clear.cgColor
                textLayer.font = self.font
                var rect = tuple.rect

                rect.origin.x *= viewWidth
                rect.size.width *= viewWidth
                rect.origin.y *= viewHeight
                rect.size.height *= viewHeight

                // Increase the size of text layer to show text of large lengths
                rect.size.width += 100
                rect.size.height += 100

                textLayer.frame = rect
                textLayer.string = tuple.text
                textLayer.foregroundColor = UIColor.green.cgColor
                self.view.layer.addSublayer(textLayer)



            }
        }
    }


}

基本上,
CameraView
被设置为
ViewController
的根视图,这就是您无法更改其大小的原因。您需要将
CameraView
设置为
ViewController
根视图的子视图,以更改其大小

类似于:

  • 选择
    ViewController.swift
  • 删除以下内容:

    private var cameraView:cameraView{
    返回视图为!CameraView
    }

  • 将所有
    cameraView
    替换为
    self.cameraView

  • 添加以下行:

    @ibvar cameraView:cameraView

  • 将所有
    self.view
    替换为
    self.cameraView

  • 选择
    Main.storyboard
  • 文档大纲
  • 转到身份检查器(
    ⌥⌘3
    )并清除
    ,该类应包含
    摄像视图
    。清除后,它应该显示
    ui视图
  • 打开
    ⇧⌘L
    )并在原始的
    摄像机视图中添加一个新的
    视图
    (可以随意调整此新视图的大小)
  • 选择此新视图并转到身份检查器(
    ⌥⌘3)并将
    类更改为
    CameraView
  • 在情节提要中选择查看控制器,然后转到连接检查器(
    ⌥⌘6
  • 连接插座
    CameraView
  • 如果您不喜欢超出
    cameraView
    范围的文本,只需在
    viewDidLoad
    中添加以下内容:

    self.cameraView.clipsToBounds = true
    
    看看这个例子,我从未尝试过,但他们添加了文本字段等