[英]How to change the size of a video view in Swift
I am new to Swift and I am trying to implement some projects. 我是Swift的新手,我正在尝试实施一些项目。 I got this code from Github and it is working fine.
我从Github那里获得了这段代码,并且运行良好。
When you click on the app, it starts a video on the iPhone screen and it detects letters and characters using 'TesseractOCR'
. 当您单击该应用程序时,它将在iPhone屏幕上启动视频,并使用
'TesseractOCR'
检测字母和字符。
The problem is the video is covering all the screen, I am not able to add any buttons. 问题是视频覆盖了所有屏幕,我无法添加任何按钮。 If I add a button, it disappears under the video.
如果我添加一个按钮,该按钮将在视频下方消失。
I tried to add session.sessionPreset = .photo
to crop the video from top and down but it did not work. 我尝试添加
session.sessionPreset = .photo
裁剪视频,但是没有用。 I also tried to add preview.sessionPreset = .photo
but did not work either 我也尝试添加
preview.sessionPreset = .photo
但也没有用
Note: Main.storyboard
is empty. 注意:
Main.storyboard
为空。
Here is the code: 这是代码:
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)
}
}
}
}
Basically the CameraView
is being set as the root view of ViewController
, which is why you cannot change its size. 基本上,将
CameraView
设置为ViewController
的根视图,这就是为什么您不能更改其大小的原因。 You need to make the CameraView
to a child view of ViewController
's root view in order to change it's size. 您需要将
CameraView
设为ViewController
根视图的子视图,以更改其大小。
Something similar to: 类似于:
ViewController.swift
ViewController.swift
Remove the following 删除以下内容
private var cameraView: CameraView { return view as! CameraView }
Replace all cameraView
with self.cameraView
用
cameraView
替换所有self.cameraView
Add the following line: 添加以下行:
@IBOutlet var cameraView: CameraView!
Replace all self.view
with self.cameraView
更换所有
self.view
与self.cameraView
Main.storyboard
Main.storyboard
Camera View
in Document Outline
Document Outline
选择Camera View
Identity Inspector
( ⌥⌘3
) and clear Class
, which should contain CameraView
. Identity Inspector
( ⌥⌘3
)并清除Class
,其中应包含CameraView
。 After you cleared it, it should show UIView
UIView
Library
( ⇧⌘L
) and add a new View
inside the original Camera View
(Feel free to adjust the size of this new view) Library
( ⇧⌘L
)并在原始“ Camera View
View
内添加一个新View
(可随意调整此新视图的大小) Identity Inspector
( ⌥⌘3
) and change the Class
to CameraView
Identity Inspector
( ⌥⌘3
),然后将“ Class
更改为CameraView
View Controller
in Storyboard and go to Connections Inspector
( ⌥⌘6
) View Controller
并转到Connections Inspector
( ⌥⌘6
) CameraView
CameraView
And if you don't like text going out of bound of cameraView
, you can simply add the following in viewDidLoad
: 而且,如果您不喜欢文字超出
cameraView
,则可以在viewDidLoad
添加以下viewDidLoad
:
self.cameraView.clipsToBounds = true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.