Utilities | iOS Document Scanner
Besides the scanning modules, Scanbot SDK also contains some utility classes that can reduce your workload, hence making your life easier:
Zoom- and scrollable image view (SBSDKZoomingImageScrollView)
- You can use it as a direct UIImageView replacement.
- You can zoom in to the image, scroll around, and when you zoom out, the image is centered within the view.
- You can add a transparent overlay that will act like a HUD above the image view.
- You can specify the margins that the image should maintain when zoomed out.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class ZoomingImageScrollViewSwiftViewController: UIViewController {
var imageViewWithZoom: SBSDKZoomingImageScrollView?
let image = UIImage(named: "documentImage")
override func viewDidLoad() {
super.viewDidLoad()
// We instantiate our new class helper.
imageViewWithZoom = SBSDKZoomingImageScrollView()
// We set the desired image.
imageViewWithZoom?.image = image
// We can add some margins.
imageViewWithZoom?.margins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
// We set an overlay on top of our image.
let overlayView = UIView()
overlayView.backgroundColor = UIColor.white.withAlphaComponent(0.3)
imageViewWithZoom?.overlayView = overlayView
// We add our view to the subview with our desired constraints.
imageViewWithZoom?.translatesAutoresizingMaskIntoConstraints = false
if let imageViewWithZoom = imageViewWithZoom {
self.view.addSubview(imageViewWithZoom)
if let image = image {
let ratio = image.size.width / image.size.height
imageViewWithZoom.widthAnchor.constraint(equalToConstant: 320).isActive = true
imageViewWithZoom.heightAnchor.constraint(equalToConstant: 320 / ratio).isActive = true
imageViewWithZoom.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
imageViewWithZoom.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
}
}
}
#import "ZoomingImageScrollViewObjcViewController.h"
@import ScanbotSDK;
@interface ZoomingImageScrollViewObjcViewController ()
@end
@implementation ZoomingImageScrollViewObjcViewController
SBSDKZoomingImageScrollView *imageViewWithZoom;
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:@"documentImage"];
// We instantiate our new class helper.
imageViewWithZoom = [[SBSDKZoomingImageScrollView alloc] init];
// We set the desired image.
imageViewWithZoom.image = image;
// We can add some margins.
imageViewWithZoom.margins = UIEdgeInsetsMake(0, 20, 0, 20);
// We set an overlay on top of our image.
UIView *overlayView = [[UIView alloc] init];
overlayView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.3];
imageViewWithZoom.overlayView = overlayView;
// We add our view to the subview with our desired constraints.
imageViewWithZoom.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:imageViewWithZoom];
if (image != nil) {
CGFloat ratio = image.size.width / image.size.height;
[imageViewWithZoom.widthAnchor constraintEqualToConstant:320].active = YES;
[imageViewWithZoom.heightAnchor constraintEqualToConstant:320 / ratio].active = YES;
[imageViewWithZoom.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
[imageViewWithZoom.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = YES;
}
}
@end
Camera Device (SBSDKCameraDevice)
- Provides the available camera devices to be used with any of the Classic or RTU-UI scanner components in Scanbot SDK.
- You can enumerate available devices using their position (front or back) and/or their type (wide, tele, ultra-wide, dual, triple).
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class CameraDeviceSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Get all the available camera devices.
let availableDevices = SBSDKCameraDevice.availableDevices
// Get all the available back camera devices.
let availableBackDevices = SBSDKCameraDevice.availableDevices(for: .back)
// Get all the desired cameras by providing the type and position.
let availableTripeCameraBackDevices = SBSDKCameraDevice.availableDevices(for: .triple, position: .back)
// Get the default back facing camera.
let defaultBackCamera = SBSDKCameraDevice.defaultBackFacingCamera
// Get the default front facing camera.
let defaultFrontCamera = SBSDKCameraDevice.defaultFrontFacingCamera
// Get the first triple back camera and create scanner components.
if let tripleCamera = availableTripeCameraBackDevices.first {
createRTUUIScanner(with: tripleCamera)
createClassicalScanner(with: tripleCamera)
}
}
func createRTUUIScanner(with device: SBSDKCameraDevice) {
// Create the camera configuration.
let cameraConfig = SBSDKUICameraConfiguration()
// Assign the device to the camera configuration.
cameraConfig.camera = device
// Assemble the scanner configuration and pass the camera configuration.
let configuration =
SBSDKUIDocumentScannerConfiguration(uiConfiguration: SBSDKUIDocumentScannerUIConfiguration(),
textConfiguration: SBSDKUIDocumentScannerTextConfiguration(),
behaviorConfiguration: SBSDKUIDocumentScannerBehaviorConfiguration(),
cameraConfiguration: cameraConfig)
// Create the RTU-UI scanner, passing the scanner configuration.
let scanner = SBSDKUIDocumentScannerViewController.createNew(configuration: configuration, delegate: nil)
}
func createClassicalScanner(with device: SBSDKCameraDevice) {
// Create the classical scanner.
let scanner = SBSDKDocumentScannerViewController(parentViewController: self,
parentView: self.view,
delegate: nil)
// Assign the device to the scanner.
scanner?.cameraDevice = device
}
}
#import "CameraDeviceObjcViewController.h"
@import ScanbotSDK;
@interface CameraDeviceObjcViewController ()
@end
@implementation CameraDeviceObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Get all the available camera devices.
NSArray<SBSDKCameraDevice*> *availableDevices = [SBSDKCameraDevice availableDevices];
// Get all the available back camera devices.
NSArray<SBSDKCameraDevice*> *availableBackDevices = [SBSDKCameraDevice availableDevicesForPosition:SBSDKCameraDevicePositionBack];
// Get all the desired cameras by providing the type and position.
NSArray<SBSDKCameraDevice*> *availableTripeCameraBackDevices = [SBSDKCameraDevice availableDevicesForType:SBSDKCameraDeviceTypeTriple
andPosition:SBSDKCameraDevicePositionBack];
// Get the default back facing camera.
SBSDKCameraDevice *defaultBackCamera = [SBSDKCameraDevice defaultBackFacingCamera];
// Get the default front facing camera.
SBSDKCameraDevice *defaultFrontCamera = [SBSDKCameraDevice defaultFrontFacingCamera];
// Get the first triple back camera and create scanner components.
SBSDKCameraDevice *tripleCamera = availableTripeCameraBackDevices.firstObject;
if (tripleCamera != nil) {
[self createRTUUIScanner:tripleCamera];
[self createClassicalScanner:tripleCamera];
}
}
- (void)createRTUUIScanner:(SBSDKCameraDevice *)device {
// Create the camera configuration.
SBSDKUICameraConfiguration *cameraConfig = [[SBSDKUICameraConfiguration alloc] init];
// Assign the device to the camera configuration.
cameraConfig.camera = device;
// Assemble the scanner configuration and pass the camera configuration.
SBSDKUIDocumentScannerConfiguration *configuration =
[[SBSDKUIDocumentScannerConfiguration alloc] initWithUiConfiguration:[SBSDKUIDocumentScannerUIConfiguration new]
textConfiguration:[SBSDKUIDocumentScannerTextConfiguration new]
behaviorConfiguration:[SBSDKUIDocumentScannerBehaviorConfiguration new]
cameraConfiguration:cameraConfig];
// Create the RTU-UI scanner, passing the scanner configuration.
SBSDKUIDocumentScannerViewController *scanner =
[SBSDKUIDocumentScannerViewController createNewWithConfiguration:configuration andDelegate:nil];
}
- (void)createClassicalScanner:(SBSDKCameraDevice *)device {
// Create the classical scanner.
SBSDKDocumentScannerViewController *scanner
= [[SBSDKDocumentScannerViewController alloc] initWithParentViewController:self parentView:self.view delegate:nil];
// Assign the device to the scanner.
scanner.cameraDevice = device;
}
@end
Image Metadata Processor (SBSDKImageMetadataProcessor)
- Lets you read, modify and write image metadata.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class ImageMetadataProcessorSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Set the desired image.
let image = UIImage(named: "documentImage")
if let image {
// Convert the image to data.
let imageData = image.jpegData(compressionQuality: 0)
// Extract the metadata.
if let imageData, let oldExtractedMetadata = SBSDKImageMetadataProcessor.extractMetadata(from: imageData) {
self.printExtractedMetadata(metadata: oldExtractedMetadata, withTitle: "OLD metadata")
// Create new metadata or modify the extracted metadata.
if let injectedMetadata = SBSDKImageMetadata(with: oldExtractedMetadata.metadataDictionary) {
injectedMetadata.title = "Scanbot SDK"
injectedMetadata.originalDate = Date()
// Inject the new metadata into the image data.
let newImageData = SBSDKImageMetadataProcessor.imageDataByInjecting(metadata: injectedMetadata, into: imageData)
// Re-extract the new metadata again.
if let newImageData,
let newExtractedMetadata = SBSDKImageMetadataProcessor.extractMetadata(from: newImageData) {
self.printExtractedMetadata(metadata: newExtractedMetadata, withTitle: "NEW metadata")
}
}
}
}
}
// Print some of the metadata fields.
func printExtractedMetadata(metadata: SBSDKImageMetadata?, withTitle title: String) {
if let metadata {
print("Begin of \(title) *************")
print("altitude: \(String(describing: metadata.altitude))")
print("latitude: \(String(describing: metadata.latitude))")
print("longitude: \(String(describing: metadata.longitude))")
print("aperture: \(String(describing: metadata.aperture))")
print("digitalizationDate: \(String(describing: metadata.digitalizationDate?.description))")
print("exposureTime: \(String(describing: metadata.exposureTime))")
print("focalLength: \(String(describing: metadata.focalLength))")
print("focalLength35mm: \(String(describing: metadata.focalLength35mm))")
print("imageHeight: \(String(describing: metadata.imageHeight))")
print("imageWidth: \(String(describing: metadata.imageWidth))")
print("isoValue: \(String(describing: metadata.ISOValue))")
print("lensMaker: \(String(describing: metadata.lensMaker))")
print("lensModel: \(String(describing: metadata.lensModel))")
print("orientation: \(String(describing: metadata.orientation))")
print("originalDate: \(String(describing: metadata.originalDate?.description))")
print("title: \(String(describing: metadata.title))")
print("metadataDictionary: \(String(describing: metadata.metadataDictionary))")
print("End of \(title) *************")
}
}
}
#import "ImageMetadataProcessorObjcViewController.h"
@import ScanbotSDK;
@interface ImageMetadataProcessorObjcViewController ()
@end
@implementation ImageMetadataProcessorObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the desired image.
UIImage *image = [UIImage imageNamed:@"documentImage"];
// Convert the image to data.
NSData *imageData = UIImageJPEGRepresentation(image, 0);
// Extract the metadata.
SBSDKImageMetadata *oldExtractedMetadata = [SBSDKImageMetadataProcessor extractMetadataFromImageData:imageData];
[self printExtractedMetadata:oldExtractedMetadata withTitle:@"OLD metadata"];
// Create new metadata or modify the extracted metadata.
SBSDKImageMetadata *injectedMetadata = [[SBSDKImageMetadata alloc]
initWithMetadataDictionary:oldExtractedMetadata.metadataDictionary];
injectedMetadata.title = @"Scanbot SDK";
injectedMetadata.originalDate = [[NSDate alloc] init];
// Inject the new metadata to the image data.
NSData *newImageData = [SBSDKImageMetadataProcessor imageDataByInjectingMetadata:injectedMetadata
intoImageData:imageData];
// Re-extract the new metadata.
SBSDKImageMetadata *newExtractedMetadata = [SBSDKImageMetadataProcessor extractMetadataFromImageData:newImageData];
[self printExtractedMetadata:newExtractedMetadata withTitle:@"NEW metadata"];
}
// Print some of the metadata fields.
- (void) printExtractedMetadata:(SBSDKImageMetadata*)metadata withTitle:(NSString*)title {
NSLog(@"Begin of %@ *************", title);
NSLog(@"altitude: %f", metadata.altitude);
NSLog(@"latitude: %f", metadata.latitude);
NSLog(@"longitude: %f", metadata.longitude);
NSLog(@"aperture: %f", metadata.aperture);
NSLog(@"digitalizationDate: %@", [metadata.digitalizationDate description]);
NSLog(@"exposureTime: %f", metadata.exposureTime);
NSLog(@"focalLength: %f", metadata.focalLength);
NSLog(@"focalLength35mm: %f", metadata.focalLength35mm);
NSLog(@"imageHeight: %lu", (unsigned long)metadata.imageHeight);
NSLog(@"imageWidth: %lu", (unsigned long)metadata.imageWidth);
NSLog(@"isoValue: %f", metadata.ISOValue);
NSLog(@"lensMaker: %@", metadata.lensMaker);
NSLog(@"lensModel: %@", metadata.lensModel);
NSLog(@"orientation: %lu", (unsigned long)metadata.orientation);
NSLog(@"originalDate: %@", [metadata.originalDate description]);
NSLog(@"title: %@", metadata.title);
NSLog(@"metadataDictionary: %@", metadata.metadataDictionary);
NSLog(@"End of %@ *************", title);
}
@end
PDF Metadata Attributes (SBSDKPDFAttributes)
- Lets you read, modify and write a PDF document's metadata.
- If you want to use this feature your app must import the
PDFKit
module.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class PDFAttributesSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Get the URL of your desired pdf file.
guard let url = Bundle.main.url(forResource: "document", withExtension: "pdf") else { return }
// Read the pdf metadata attributes from the PDF at the url.
let attributes = SBSDKPDFAttributes(pdfURL: url)!
// Change the pdf attributes.
attributes.title = "A Scanbot Demo PDF"
attributes.author = "ScanbotSDK Development"
attributes.creator = "ScanbotSDK for iOS"
attributes.subject = "A demonstration of ScanbotSDK PDF creation."
attributes.keywords = ["PDF", "Scanbot", "SDK"]
// Inject the new pdf metadata attributes into your pdf at the same url.
do {
try attributes.saveToPDFFile(at: url)
}
catch {
// Catch the error.
}
}
}
#import "PDFAttributesObjcViewController.h"
@import ScanbotSDK;
@interface PDFAttributesObjcViewController ()
@end
@implementation PDFAttributesObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Get the URL of your desired pdf file.
NSURL *url = [[NSBundle mainBundle] URLForResource:@"document" withExtension:@"pdf"];
// Read the pdf metadata attributes from the PDF at the url.
SBSDKPDFAttributes *attributes = [[SBSDKPDFAttributes alloc] initWithPdfURL:url];
// Edit the pdf metadata.
attributes.title = @"A Scanbot Demo PDF";
attributes.author = @"ScanbotSDK Development";
attributes.creator = @"ScanbotSDK for iOS";
attributes.subject = @"A demonstration of ScanbotSDK PDF creation.";
attributes.keywords = @[@"PDF", @"Scanbot", @"SDK"];
// Inject the new pdf metadata in your pdf at the same url or in a new created url.
NSError *error = nil;
[attributes saveToPDFFileAt:url error:&error];
// Handle error.
if (error) {
NSLog(@"Error caught: %@", error.localizedDescription);
} else {
NSLog(@"Save successful");
}
}
@end
Text Orientation Recognition (SBSDKTextLayoutRecognizer)
- Determines the orientation of text in an image.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class TextOrientationRecognizerSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Initialize an instance of the recognizer.
let recognizer = SBSDKTextLayoutRecognizer()
// Set the desired image.
if let image = UIImage(named: "testDocument") {
// Recognize the text orientation.
let oldOrientation = recognizer.recognizeTextOrientation(on: image)
// Handle the result.
self.printOrientationResult(orientation: oldOrientation)
// Recognize the text orientation, but request a minimum confidence of 2.0.
let orientationWithConfidence = recognizer.recognizeTextOrientation(on: image, with: 2.0)
// Handle the result.
self.printOrientationResult(orientation: orientationWithConfidence)
// Rotate the image to portrait mode if possible.
let newImage = self.rotateImageToPortraitMode(image: image, orientation: orientationWithConfidence)
}
}
// Rotate the image according to the recognized orientation.
func rotateImageToPortraitMode(image: UIImage, orientation: SBSDKTextOrientation) -> UIImage? {
switch orientation {
case .notRecognized, .lowConfidence, .up:
return image
case .right:
return image.sbsdk_imageRotatedCounterClockwise(1)
case .down:
return image.sbsdk_imageRotatedClockwise(2)
case .left:
return image.sbsdk_imageRotatedCounterClockwise(3)
default:
return image
}
}
// Print the recognized orientation to the console.
func printOrientationResult(orientation: SBSDKTextOrientation) {
switch orientation {
case .notRecognized:
print("Text orientation was not recognized (bad image quality, etc).")
case .lowConfidence:
print("Text was recognized, but the confidence of recognition is too low.")
case .up:
print("Text is not rotated.")
case .right:
print("Text is rotated 90 degrees clockwise.")
case .down:
print("Text is rotated 180 degrees clockwise.")
case .left:
print("Text is rotated 270 degrees clockwise.")
default:
print(orientation.rawValue)
}
}
}
#import "TextOrientationRecognizerObjcViewController.h"
@import ScanbotSDK;
@interface TextOrientationRecognizerObjcViewController ()
@end
@implementation TextOrientationRecognizerObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// We initialize an instance of our recognizer.
SBSDKTextLayoutRecognizer *recognizer = [[SBSDKTextLayoutRecognizer alloc] init];
// Set the desired image.
UIImage *image = [UIImage imageNamed:@"testDocument"];
if (image != nil) {
// Recognize the text orientation.
SBSDKTextOrientation oldOrientation = [recognizer recognizeTextOrientationOnImage:image];
// Handle the result.
[self printOrientationResultForOrientation:oldOrientation];
// Recognize the text orientation, but request a minimum confidence of 2.0.
SBSDKTextOrientation orientationWithConfidence = [recognizer recognizeTextOrientationOnImage:image
withConfidence:2.0f];
// Handle the result.
[self printOrientationResultForOrientation:oldOrientation];
// Rotate the image to portrait mode if possible.
UIImage *newImage = [self rotateImageToPortraitModeWithImage:image withOrientation:orientationWithConfidence];
}
}
// Rotate the image according to the recognized orientation.
- (UIImage*) rotateImageToPortraitModeWithImage:(UIImage*)image withOrientation:(SBSDKTextOrientation)orientation {
switch (orientation) {
case SBSDKTextOrientationNotRecognized:
case SBSDKTextOrientationLowConfidence:
case SBSDKTextOrientationUp:
return image;
break;
case SBSDKTextOrientationRight:
return [image sbsdk_imageRotatedCounterClockwise:1];
break;
case SBSDKTextOrientationDown:
return [image sbsdk_imageRotatedClockwise:2];
break;
case SBSDKTextOrientationLeft:
return [image sbsdk_imageRotatedCounterClockwise:3];
break;
default:
return image;
break;
}
}
// Print the recognized orientation to the console.
- (void)printOrientationResultForOrientation:(SBSDKTextOrientation)orientation {
switch (orientation) {
case SBSDKTextOrientationNotRecognized:
NSLog(@"Text orientation was not recognized (bad image quality, etc).");
break;
case SBSDKTextOrientationLowConfidence:
NSLog(@"Text was recognized, but the confidence of recognition is too low.");
break;
case SBSDKTextOrientationUp:
NSLog(@"Text is not rotated.");
break;
case SBSDKTextOrientationRight:
NSLog(@"Text is rotated 90 degrees clockwise.");
break;
case SBSDKTextOrientationDown:
NSLog(@"Text is rotated 180 degrees clockwise.");
break;
case SBSDKTextOrientationLeft:
NSLog(@"Text is rotated 270 degrees clockwise.");
break;
default:
break;
}
}
@end
Document Quality Analyzer (SBSDKDocumentQualityAnalyzer)
- Analyzes the quality of text in a document on a still image.
- The result is an enum of type
SBSDKDocumentQuality
.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class DocumentQualityAnalyzerSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the analyzer.
let analyzer = SBSDKDocumentQualityAnalyzer()
// Set the desired image.
if let image = UIImage(named: "testDocument") {
// Analyze the quality of the image.
let quality = analyzer.analyze(on: image)
// Handle the result.
self.printResult(quality: quality)
}
}
// Print the result.
func printResult(quality: SBSDKDocumentQuality) {
switch quality {
case .noDocument:
print("No document was found")
case .veryPoor:
print("The quality of the document is very poor")
case .poor:
print("The quality of the document is poor")
case .reasonable:
print("The quality of the document is reasonable")
case .good:
print("The quality of the document is good")
case .excellent:
print("The quality of the document is excellent")
@unknown default: break
}
}
}
#import "DocumentQualityAnalyzerObjcViewController.h"
@import ScanbotSDK;
@interface DocumentQualityAnalyzerObjcViewController ()
@end
@implementation DocumentQualityAnalyzerObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Initialize the analyzer.
SBSDKDocumentQualityAnalyzer *analyzer = [[SBSDKDocumentQualityAnalyzer alloc] init];
// Set the desired image.
UIImage *image = [UIImage imageNamed:@"testDocument"];
// Analyze the quality of the image.
SBSDKDocumentQuality quality = [analyzer analyzeOnImage:image];
// Handle the result.
[self printResult:quality];
}
// Print the result.
- (void) printResult:(SBSDKDocumentQuality)quality {
switch (quality) {
case SBSDKDocumentQualityNoDocument:
NSLog(@"No document was found");
break;
case SBSDKDocumentQualityVeryPoor:
NSLog(@"The quality of the document is very poor");
break;
case SBSDKDocumentQualityPoor:
NSLog(@"The quality of the document is poor");
break;
case SBSDKDocumentQualityReasonable:
NSLog(@"The quality of the document is reasonable");
break;
case SBSDKDocumentQualityGood:
NSLog(@"The quality of the document is good");
break;
case SBSDKDocumentQualityExcellent:
NSLog(@"The quality of the document is excellent");
break;
}
}
@end
Image Storages (SBSDKIndexedImageStorage, SBSDKKeyedImageStorage)
SBSDKIndexedImageStorage
andSBSDKKeyedImageStorage
are thread-safe and persistent storage for images.- They can be used to store and retrieve images in an array-fashioned style (indexed) or dictionary-fashioned style (keyed) to and from the device disk.
- Both allow the usage of an encrypter which encrypts the data when writing it to the disk and decrypts the data when reading it from the disk.
- These classes conform to the
SBSDKImageStoring
protocol. Custom image storage can be implemented and used within Scanbot SDK by conforming to this protocol.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class ImageStoringSwiftViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Initialize a folder URL to persist the images to.
let documentsURL = SBSDKStorageLocation.applicationDocumentsFolderURL.appendingPathComponent("Images", isDirectory: true)
// Create a storage location object. This will create the folder on the filesystem if neccessary.
let documentsLocation = SBSDKStorageLocation(baseURL: documentsURL)
// Initialize an indexed image storage at this location.
// The indexed image storage is an array-like storage.
let imageStorage = SBSDKIndexedImageStorage(storageLocation: documentsLocation,
fileFormat: .PNG,
encrypter: nil)!
if let image = UIImage(named: "testDocument") {
// Save an image to the storage.
let isAdded = imageStorage.add(image)
// Check the result.
print("Image added successfully: \(isAdded)")
}
// Check the number of images in the storage.
print("Images in storage: \(imageStorage.imageCount)")
// Create and attach an encrypter to the storage. This will encrypt the image data, before it is written to disk
// and decrypt it after it is read from disk.
// Setting the encrypter does not encrypt existing images in the storage, only the images that are added to the
// storage after setting the encrypter.
imageStorage.encrypter = SBSDKAESEncrypter(password: "xxxxx", mode: .AES256)
// Store an image from a URL. This does not load the image and has a very low memory footprint.
if let url = Bundle.main.url(forResource: "imageDocument", withExtension: "png") {
// Copy the image from the URL to the storage.
let isAdded = imageStorage.addImage(from: url)
// Check the result.
print("Image from URL was added successfully : \(isAdded)")
}
// Make sure that the indices are valid before moving an image from one index to another.
if imageStorage.imageCount > 1 {
// Move the image at index 1 to index 0.
let isMoved = imageStorage.moveImage(from: 1, to: 0)
print("Image was moved successfully: \(isMoved)")
}
// Make sure that the index is valid.
if imageStorage.imageCount > 1 {
// Remove the image at index 1.
imageStorage.removeImage(at: 1)
}
// The image storage is persisted on disk.
// When the images are no longer needed they should be removed to free the disk space.
// Remove all images from the storage.
imageStorage.removeAll()
}
}
#import "ImageStoringObjcViewController.h"
@import ScanbotSDK;
@interface ImageStoringObjcViewController ()
@end
@implementation ImageStoringObjcViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Initialize a folder URL to persist the images to.
NSURL *documentsURL = [[SBSDKStorageLocation applicationDocumentsFolderURL] URLByAppendingPathComponent:@"Images"];
// Create a storage location object. This will create the folder on the filesystem if neccessary.
SBSDKStorageLocation *documentsLocation = [[SBSDKStorageLocation alloc] initWithBaseURL:documentsURL];
// Initialize an indexed image storage at this location.
// The indexed image storage is an array-like storage.
SBSDKIndexedImageStorage *imageStorage
= [[SBSDKIndexedImageStorage alloc] initWithStorageLocation:documentsLocation
fileFormat:SBSDKImageFileFormatPNG
encrypter:nil];
UIImage *image = [UIImage imageNamed:@"testDocument"];
// Save an image to our location.
BOOL isAdded = [imageStorage addImage:image];
// Check the result.
NSLog(@"Image added successfully : %@", isAdded ? @"YES" : @"NO");
// Check the number of images in the storage.
NSLog(@"Image Count: %lu", (unsigned long)[imageStorage imageCount]);
// Create and attach an encrypter to the storage. This will encrypt the image data, before it it written to disk
// and decrypt it after it is read from disk.
// Setting the encrypter does not encrypt existing images in the storage, only the images that are added to the
// storage after setting the encrypter.
imageStorage.encrypter = [[SBSDKAESEncrypter alloc] initWithPassword:@"xxxxx" mode:SBSDKAESEncrypterModeAES256];
// Store an image from a URL. This does not load the image and has a very low memory footprint.
NSURL *url = [[NSBundle mainBundle] URLForResource:@"imageDocument" withExtension:@"png"];
// Copy the image from the URL to the storage.
BOOL isAddedFromURL = [imageStorage addImageFromURL:url];
// Check the result.
NSLog(@"Image from URL was added successfully : %@", isAddedFromURL ? @"YES" : @"NO");
// Make sure that the indices are valid before moving an image from one index to another.
if (imageStorage.imageCount > 1) {
// Move the image at index 1 to index 0.
BOOL isMoved = [imageStorage moveImageFromIndex:1 toIndex:0];
NSLog(@"Image was moved successfully : %@", isMoved ? @"YES" : @"NO");
}
// Make sure that the index is valid.
if (imageStorage.imageCount > 1) {
// Remove the image at index 1.
[imageStorage removeImageAtIndex:1];
}
// The image storage is persisted on disk.
// When the images are no longer needed they should be removed to free the disk space.
// Remove all images from the storage.
[imageStorage removeAllImages];
}
@end
Sound Controller (SBSDKSoundController)
- Can play a beep sound, custom sounds loaded from a URL and/or a vibration.
- Swift
- Objective-C
import UIKit
import ScanbotSDK
class SoundControllerSwiftViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Initialize the sound controller.
let soundController = SBSDKSoundController()
// Play the beep sound and vibrate after 2 seconds.
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
// Beep.
soundController.playBleepSound()
// Vibrate.
soundController.vibrate()
})
// Play a sound from a custom url and vibrate after 3 seconds.
guard let url = Bundle.main.url(forResource: "sound", withExtension: "m4a") else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
// Play custom sound.
soundController.playCustomSound(from: url)
// Vibrate.
soundController.vibrate()
})
}
}
#import "SoundControllerObjcViewController.h"
@import ScanbotSDK;
@interface SoundControllerObjcViewController ()
@end
@implementation SoundControllerObjcViewController
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// Initialize the sound controller.
SBSDKSoundController *soundController = [[SBSDKSoundController alloc] init];
// Play the beep sound and vibrate after 2 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// Beep.
[soundController playBleepSound];
// Vibration.
[soundController vibrate];
});
// Play a sound from a custom url and vibrate after 3 seconds.
NSURL *url = [[NSBundle mainBundle] URLForResource:@"sound" withExtension:@"m4a"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// Play custom sound.
[soundController playCustomSoundFromURL:url];
// Vibrate.
[soundController vibrate];
});
}
@end
Want to scan longer than one minute?
Generate a free trial license to test the Scanbot SDK thoroughly.
Get your free Trial LicenseWhat do you think of this documentation?
What can we do to improve it? Please be as detailed as you like.