-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathMultiScanResultViewController.swift
More file actions
194 lines (150 loc) · 7.65 KB
/
Copy pathMultiScanResultViewController.swift
File metadata and controls
194 lines (150 loc) · 7.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//
// MultiScanResultViewController.swift
// DocumentScannerRTUUIExample
//
// Created by Rana Sohaib on 29.08.23.
//
import ScanbotSDK
final class MultiScanResultViewController: UIViewController {
var document: SBSDKScannedDocument!
@IBOutlet private var exportButton: UIButton!
@IBOutlet private var collectionView: UICollectionView!
// Apply Filter
@IBAction private func filterButtonTapped(_ sender: UIButton) {
let filterListViewController = FilterListViewController.make()
// Filter selection callback handler
filterListViewController.selectedFilter = { [weak self] selectedFilter in
guard let self else { return }
let numberOfPages = self.document.pages.count
do {
try (0..<numberOfPages).forEach { index in
try self.document.page(at: index).filters = selectedFilter != nil ? [selectedFilter!] : []
}
self.collectionView.reloadData()
} catch {
sbsdk_showError(error)
}
}
navigationController?.present(filterListViewController, animated: true)
}
// Export
@IBAction private func exportButtonTapped(_ sender: UIButton) {
showExportDialogue(sender)
}
}
extension MultiScanResultViewController {
// Export to PDF
private func exportPDF() {
// Set the name and path for the pdf file
let name = "ScanbotSDK_PDF_Example.pdf"
let pdfURL = SBSDKStorageLocation.applicationDocumentsFolderURL.appendingPathComponent(name)
// Create the PDF rendering options object with default options.
let configuration = SBSDKPDFConfiguration()
// Create and set the OCR configuration for HOCR.
let options = SBSDKOCREngineConfiguration.scanbotOCR()
do {
// Generate the document into a searchable PDF at the specified file url
let generator = try SBSDKPDFGenerator(configuration: configuration,
ocrConfiguration: options,
useEncryptionIfAvailable: false)
// Start the generation operation and store the SBSDKProgress to watch the progress or cancel the operation.
let progress = generator.generate(from: document, output: pdfURL) { [weak self] finished, error in
guard let self else { return }
if finished && error == nil {
// Present the share screen
self.share(url: pdfURL)
} else if let sdkError = error as? SBSDKError, sdkError.isCanceled {
// The operation was canceled. Handle if needed.
} else if let error {
// An error occurred during the pdf generation. Show an error alert.
self.sbsdk_showError(error)
}
}
} catch {
// An error occurred during the pdf generation. Show an error alert.
sbsdk_showError(error)
}
}
// Export to TIFF
private func exportTIFF() {
// Set the name and path for the TIFF file
let name = "ScanbotSDK_TIFF_Example.tiff"
let fileURL = SBSDKStorageLocation.applicationDocumentsFolderURL.appendingPathComponent(name)
// Define the generation parameters for the TIFF
// In this case using a custom binarization filter with a preset 4 when exporting as TIFF
// as an optimal setting
let tiffGeneratorParameters = SBSDKTIFFGeneratorParameters.defaultParametersForBinaryImages
tiffGeneratorParameters.dpi = 300
tiffGeneratorParameters.compression = .ccittT6
let customFilter = SBSDKCustomBinarizationFilter()
customFilter.preset = .preset4
tiffGeneratorParameters.binarizationFilter = customFilter
do {
// Create and use `SBSDKTIFFGenerator` to write TIFF at the specified file url
let tiffGenerator = try SBSDKTIFFGenerator(parameters: tiffGeneratorParameters, useEncryptionIfAvailable: false)
try tiffGenerator.generate(from: document, to: fileURL)
// Present the share screen if file is successfully written
share(url: fileURL)
} catch {
sbsdk_showError(error)
}
}
}
extension MultiScanResultViewController {
// To show export dialogue
private func showExportDialogue(_ sourceButton: UIButton) {
let alertController = UIAlertController(title: "Export Document",
message: nil,
preferredStyle: .alert)
let pdfAction = UIAlertAction(title: "Export as PDF", style: .default) { _ in self.exportPDF() }
let tiffAction = UIAlertAction(title: "Export as TIFF (1-bit)", style: .default) { _ in self.exportTIFF() }
let cancelActon = UIAlertAction(title: "Cancel", style: .cancel)
let actions = [pdfAction, tiffAction, cancelActon]
actions.forEach { alertController.addAction($0) }
self.present(alertController, animated: true)
}
// To show activity (share) screen
private func share(url: URL) {
let activityViewController = UIActivityViewController(activityItems: [url],
applicationActivities: nil)
if let popoverPresentationController = activityViewController.popoverPresentationController {
popoverPresentationController.sourceView = exportButton
}
present(activityViewController, animated: true)
}
}
extension MultiScanResultViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return document.pages.count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiScanResultCollectionViewCell",
for: indexPath) as! MultiScanResultCollectionViewCell
do {
// Retrieve the document page
let page = try document.page(at: indexPath.row)
// Check detection status
if page.documentDetectionStatus == .errorNothingDetected {
// Use the full original image if nothing detected
cell.resultImageView.image = try page.originalImage?.toUIImage()
} else {
// Use the cropped image otherwise
cell.resultImageView.image = try page.documentImage?.toUIImage()
}
} catch {
// An error occurred while retrieving the page or images.
sbsdk_showError(error)
}
return cell
}
}
extension MultiScanResultViewController {
static func make(with document: SBSDKScannedDocument) -> MultiScanResultViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let resultViewController = storyboard.instantiateViewController(identifier: "MultiScanResultViewController") as! MultiScanResultViewController
resultViewController.document = document
return resultViewController
}
}