Hi, thank you for your replies, I realise that I did not provide enough code, so below is my ViewController which links to my Storyboard and defines all its actions. Many thanks for your help.
//
// ViewController.swift
// TextRecognizeInImage
//
// Created by ############# on 21/10/2022.
//
import SwiftUI
import UIKit
import Vision
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var button: UIButton!
@IBOutlet weak var shareButton: UIButton!
var request = VNRecognizeTextRequest(completionHandler: nil)
override func viewDidLoad() {
super.viewDidLoad()
button.backgroundColor = .systemCyan // Background colour of the select photo button
button.setTitle("Take Picture", for: .normal)
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 25
button.layer.borderWidth = 20
button.layer.borderColor = UIColor.systemCyan.cgColor
shareButton.layer.cornerRadius = 25
shareButton.layer.borderWidth = 10
shareButton.layer.borderColor = UIColor.systemCyan.cgColor
stopAnimating()
}
private func startAnimating() {
self.activityIndicator.startAnimating()
}
private func stopAnimating(){
self.activityIndicator.stopAnimating()
}
@IBAction func takePictureButton(_ sender: Any) {
setupGallary()
}
private func setupGallary(){
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
let imageTaker = UIImagePickerController()
imageTaker.sourceType = .camera
imageTaker.allowsEditing = true
imageTaker.delegate = self
present(imageTaker, animated: true)
}
}
private func setupVisionTextRecognizeImage(image: UIImage?){
// setup TextRecognition
var textString = ""
request = VNRecognizeTextRequest(completionHandler: { (request, error)in
guard let observations = request.results as?[VNRecognizedTextObservation] else {fatalError("Recieved Invalid Observation")}
for observation in observations{
guard let topCandidate = observation.topCandidates(1).first else{
print("No candidate")
continue
}
textString += "\n\(topCandidate.string)"
DispatchQueue.main.async{
self.stopAnimating()
self.textView.text = textString
}
}
})
request.customWords = ["Cust0m"]
request.minimumTextHeight = 0.03125
request.recognitionLevel = .accurate
request.recognitionLanguages = ["en_UK", "en-US", "fr-FR", "it-IT", "de-DE", "es-ES", "pt-BR", "zh-Hans", "zh-Hant", "yue-Hans", "yue-Hant", "ko-KR", "ja-JP", "ru-RU", "uk-UA"]
request.usesLanguageCorrection = true
let requests = [request]
// creating request handler
DispatchQueue.global(qos: .userInitiated).async{
guard let img = image?.cgImage else {fatalError("Missing image to scan")}
let handle = VNImageRequestHandler(cgImage: img, options: [:])
try? handle.perform(requests)
}
}
@IBAction func shareButton(_ sender: Any) {
self.enterTextViaAlert()
}
private func enterTextViaAlert(){
self.convertToPdfFileAndShare()
}
private func convertToPdfFileAndShare(){
let fmt = UIMarkupTextPrintFormatter(markupText: self.textView.text)
// 2. Assign print formatter to UIPrintPageRenderer
let render = UIPrintPageRenderer()
render.addPrintFormatter(fmt, startingAtPageAt: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
render.setValue(page, forKey: "paperRect")
render.setValue(page, forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
for i in 0..<render.numberOfPages {
UIGraphicsBeginPDFPage();
render.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext();
// 5. Save PDF file
guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("output").appendingPathExtension("pdf")
else { fatalError("Destination URL not created")}
pdfData.write(to: outputURL, atomically: true)
print("open \(outputURL.path)")
if FileManager.default.fileExists(atPath: outputURL.path){
let url = URL(fileURLWithPath: outputURL.path)
let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [url], applicationActivities: nil)
let excludedActivities = [UIActivity.ActivityType.postToFlickr, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.message, UIActivity.ActivityType.mail, UIActivity.ActivityType.print, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.saveToCameraRoll, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToFlickr, UIActivity.ActivityType.postToVimeo,UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToTencentWeibo]
activityViewController.excludedActivityTypes = excludedActivities
activityViewController.popoverPresentationController?.sourceView=self.view
//If user on iPad
if UIDevice.current.userInterfaceIdiom == .pad {
if activityViewController.responds(to: #selector(getter: UIViewController.popoverPresentationController)) {
}
}
present(activityViewController, animated: true, completion: nil)
}
else {
print("document was not found")
}
}
private func textFieldDidEndEditing(_ textField: UITextField) {
guard (textField.text?.count ?? 0)>0 else{ return }
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey :Any]){
picker.dismiss(animated: true, completion: nil)
startAnimating()
self.textView.text = ""
let image = info[UIImagePickerController.InfoKey.originalImage]as?UIImage
self.imageView.image = image
setupVisionTextRecognizeImage(image: image)
}
}