Skip to main content

Barcode Scanner | Flutter Barcode Scanner

Storage#

By default the native Scanbot Barcode Scanner SDKs as well as the Plugin itself use the internal and secure storage locations for all snapped barcode image files.

  • On Android all files will be stored in the internal files directory of your application. No permissions are required for your app to read or write files in this directory.

  • On iOS all files will be stored in the Application Support folder of your application.

Storage Encryption#

The Scanbot SDK provides the ability to store the generated image files (JPG, PNG), PDF, and TIFF files encrypted. This feature provides an additional level of security to the default secure storage locations of the native SDKs.

By default the file encryption is disabled. To enable it you have to pass the following config parameters on SDK initialization:

  • password: A secure password or passphrase to derive the AES key for encryption/decryption.
  • mode: Encryption mode, AES128 or AES256 (default and recommended).
 var config = ScanbotSdkConfig(          encryptionParameters : EncryptionParameters(password: "password",                                                      mode: FileEncryptionMode.AES256)); await ScanbotBarcodeSdk.initScanbotSdk(config);

By activating the storage encryption the native Scanbot SDKs will use the built-in AES 128 or AES 256 encryption. All generated image files (JPG, PNG) including the preview image files, as well as the exported PDF files will be encrypted in memory and stored as encrypted data files on the device storage.

The Scanbot SDK derives the AES key from the given password, an internal salt value, and the internal number of iterations using the PBKDF2 function.

When applying image operations like cropping, rotation or image filters, the Scanbot SDK will decrypt the image file in memory, apply the changes, encrypt and store them again.

Also see Handle Encrypted Images.

Customize Storage Location#

It is strongly recommended to use the default storage location. However, you can override the storage directory on initialization of the Plugin. The initializeSdk method can take an optional parameter storageBaseDirectory to set a custom storage location.

Directory storageDirectory;if (Platform.isAndroid) {  storageDirectory = await getExternalStorageDirectory();}if (Platform.isIOS) {  storageDirectory = await getApplicationDocumentsDirectory();}
// Please note: getExternalStorageDirectory() and getApplicationDocumentsDirectory()// are provided via 3rd-party plugins like "path_provider".
var config = ScanbotSdkConfig(  storageBaseDirectory: "${directory.path}/my_custom_storage",  ...);await ScanbotBarcodeSdk.initScanbotSdk(config);

The value of the storageBaseDirectory must be a file URL ('file:///...) pointing to a valid platform-specific file system path. If this directory does not exist yet, the Plugin will try to create it. To work with the file system we recommend the Flutter Plugin path_provider

For the full demo code please checkout our example app on GitHub.

โš ๏ธ Note: When overriding the default storage location, make sure

  • you have implemented a suitable storage permissions request handling on Android
  • you fully understand the consequences regarding the accessibility (security) of the produced document files

๐Ÿ‘‰ For more details about the storage locations on Android and iOS please also see:

Storage Cleanup#

There is no automatic file clean mechanism in this Plugin. Your app should decide when the perfect time is to remove the optional barcode image files snapped by this Plugin.

To avoid storage space issues caused by too many produced image files, it is strongly recommended implementing a suitable cleanup functionality based on the requirements of your app. This Plugin provides the following helper methods to keep the storage clean:

Barcode and QR Code Scanning UI#

Barcode Scanner#

ScanbotBarcodeSdk.startBarcodeScanner(BarcodeScannerConfiguration config) Opens a Scanning UI for barcodes and QR codes.

alt

var config = BarcodeScannerConfiguration(  barcodeFormats: [BarcodeFormat.CODE_128, BarcodeFormat.DATA_MATRIX],  topBarBackgroundColor: Colors.blueAccent,  finderTextHint: "Please align a barcode in the frame to scan it.",  cancelButtonTitle: "Cancel",  flashEnabled: true,  ...);var result = await ScanbotBarcodeSdk.startBarcodeScanner(config);// result.barcodeItems[n] ...

Result:

  • result.operationResult - SUCCESS if a barcode was detected, ERROR if the user has canceled the operation (tapped on the "cancel" button).
  • result.barcodeItems - List of recognized barcodes as items of BarcodeItem type.
  • result.barcodeImageURI - Optional file URI of the barcode image. See the config parameter barcodeImageGenerationType to enable image snapping.

BarcodeItem structure:

  • BarcodeItem.barcodeFormat - Format of detected barcode/QR code (e.g. "CODE_128", "EAN_13", "QR_CODE", etc).
  • BarcodeItem.text - Raw text value of detected barcode/QR code.

BarcodeScannerConfiguration#

Use this configuration class to customize the UI and the behaviour of the Barcode Scanner UI. All config properties are optional.

BarcodeScannerConfiguration:

  /// Background color of the top toolbar.  Color? topBarBackgroundColor;
  /// The color of the titles of all buttons in the top toolbar.  Color? topBarButtonsColor;
  /// Background color outside the finder window.  Color? cameraOverlayColor;
  /// The color of the finder window's outline.  Color? finderLineColor;
  /// The color of the text hint under the finder window.  Color? finderTextHintColor;
  bool? cancelButtonHidden;
  /// Title of the cancel button.  String? cancelButtonTitle;
  /// Title of the button that opens the screen where the user can allow  /// the usage of the camera by the app.  String? enableCameraButtonTitle;
  /// Text that will be displayed when the app  /// is not allowed to use the camera, prompting the user  /// to enable the usage of the camera.  String? enableCameraExplanationText;
  /// Text hint shown under the finder window.  String? finderTextHint;    /// The color of the titles of all inactive buttons in the top toolbar.  Color? topBarButtonsInactiveColor;    /// Cancel scanning and close view on timeout.  int? autoCancelTimeout;
  /// Aspect ratio of finder view.  FinderAspectRatio? finderAspectRatio;
  /// Thickness of the finder window's outline.  int? finderLineWidth;
  /// Controls whether to play a beep sound after a successful detection.  /// Default value is TRUE.  bool? successBeepEnabled;
  /// Controls whether the flash should be initially enabled.  /// The default value is FALSE.  bool? flashEnabled;
  /// Orientation lock mode of the camera: PORTRAIT or LANDSCAPE.  /// By default the camera orientation is not locked.  CameraOrientationMode? orientationLockMode;
  /// Barcode formats which need to be recognized.  List<BarcodeFormat>? barcodeFormats;
  /// Additional parameters for tweaking the detection of barcodes.  BarcodeAdditionalParameters? additionalParameters;
  /// Param that handle whether we need to save image from camera preview or make a snapshot while snapping barcode  /// image uri will be returned in [BarcodeScanningResult.snappedImage] property  BarcodeImageGenerationType barcodeImageGenerationType 
  /// Type of engine to be used in barcode scanner  EngineMode engineMode;
  ///Set current zoom by a linear zoom value ranging from 0f to 1.0f. Optical Zoom Level 0f represents the minimum zoom while Optical Zoom Level 1.0f represents the maximum zoom.  ///Default value is 0f.  double? cameraZoomFactor;

Batch Barcode Scanner#

ScanbotBarcodeSdk.startBatchBarcodeScanner(BatchBarcodeScannerConfiguration config)

Opens a Scanning UI for batch barcodes.

alt

var config = BatchBarcodeScannerConfiguration(  barcodeFormats: [BarcodeFormat.CODE_128, BarcodeFormat.DATA_MATRIX],  topBarBackgroundColor: Colors.blueAccent,  finderTextHint: "Please align a barcode in the frame to scan it.",  flashEnabled: true,  ...);var result = await ScanbotBarcodeSdk.startBatchBarcodeScanner(config);// result.barcodeItems[n] ...

Result:

  • result.operationResult - SUCCESS if a barcode was detected, ERROR if the user has canceled the operation (tapped on the "cancel" button).
  • result.barcodeItems - List of recognized barcodes as items of BarcodeItem type.

BarcodeItem structure:

  • BarcodeItem.barcodeFormat - Format of detected barcode/QR code (e.g. "CODE_128", "EAN_13", "QR_CODE", etc).
  • BarcodeItem.text - Raw text value of detected barcode/QR code.

BatchBarcodeScannerConfiguration#

Use this configuration class to customize the UI and the behaviour of the Batch Barcodes Scanner UI. All config properties are optional.

BatchBarcodeScannerConfiguration:

  /// Change data representation for scanned list items  BarcodeDataFormatter? barcodeFormatter;
  /// The background color of the top toolbar.  Color? topBarBackgroundColor;
  /// The color of the titles of all buttons in the top toolbar.  Color? topBarButtonsColor;
  /// The color of the titles of all inactive buttons in the top toolbar.  Color? topBarButtonsInactiveColor;
  /// The color of barcodes count text  Color? barcodesCountTextColor;
  /// The color of barcodes details action  Color? detailsActionColor;
  /// The color of barcodes details background  Color? detailsBackgroundColor;
  /// The color of barcodes details background  Color? detailsPrimaryColor;
  /// The background color outside the finder window.  Color? cameraOverlayColor;
  /// The color of the finder window's outline.  Color? finderLineColor;
  /// The color of the text hint under the finder window.  Color? finderTextHintColor;
  bool? cancelButtonHidden;
  /// Title of the cancel button.  String? cancelButtonTitle;
  /// Title of the button that opens the screen where the user can allow  /// the usage of the camera by the app.  String? enableCameraButtonTitle;
  /// Text that will be displayed when the app  /// is not allowed to use the camera, prompting the user  /// to enable the usage of the camera.  String? enableCameraExplanationText;
  /// Text hint shown under the finder window.  String? finderTextHint;
  /// Text of submit button.  String? submitButtonTitle;
  /// Text of clear button.  String? clearButtonTitle;
  /// Text of count text.  String? barcodesCountText;
  /// Text of fetch state text.  String? fetchingStateText;
  /// Text when there are no scanned barcodes yet.  String? noBarcodesTitle;
  /// Aspect ratio of finder view.  FinderAspectRatio? finderAspectRatio;
  /// Thickness of the finder window's outline.  int? finderLineWidth;
  /// Controls whether to play a beep sound after a successful detection.  /// Default value is TRUE.  bool? successBeepEnabled;
  /// Controls whether the flash should be initially enabled.  /// The default value is FALSE.  bool? flashEnabled;
  /// Additional parameters for tweaking the detection of barcodes.  BarcodeAdditionalParameters? additionalParameters;
  /// Orientation lock mode of the camera: PORTRAIT or LANDSCAPE.  /// By default the camera orientation is not locked.
  CameraOrientationMode? orientationLockMode;
  /// Barcode formats which need to be recognized.  List<BarcodeFormat>? barcodeFormats;
  /// Type of engine to be used in barcode scanner  EngineMode engineMode;

Barcode Detection from Still Images#

ScanbotBarcodeSdk.detectFromImageFile(Uri file, List<BarcodeFormat> barcodeFormats) This method provides the functionality of detecting barcodes from a still image, e.g. a JPG image from Photo Library or other source. The image must be passed as a file URI.

Parameters:

  • Uri file - A valid file URI of the image (e.g. file:///some/path/image-with-barcodes.jpg). Supported image formats are JPG and PNG. Please make sure your app has the appropriate read permission to access this file.
  • List<BarcodeFormat> barcodeFormats - Optional list of barcode formats to recognize.

Result:

  • result.barcodeItems - List of recognized barcodes as items of BarcodeItem type.

Barcode Format#

The following barcode formats are currently supported on Android and iOS.

1D Barcodes#

  • BarcodeFormat.AZTEC
  • BarcodeFormat.CODABAR
  • BarcodeFormat.CODE_39
  • BarcodeFormat.CODE_93
  • BarcodeFormat.CODE_128
  • BarcodeFormat.DATA_MATRIX
  • BarcodeFormat.EAN_8
  • BarcodeFormat.EAN_13
  • BarcodeFormat.ITF
  • BarcodeFormat.PDF_417
  • BarcodeFormat.QR_CODE
  • BarcodeFormat.RSS_14
  • BarcodeFormat.RSS_EXPANDED
  • BarcodeFormat.UPC_A
  • BarcodeFormat.UPC_E
  • BarcodeFormat.MSI_PLESSEY

2D Barcodes#

  • BarcodeFormat.QR_CODE
  • BarcodeFormat.AZTEC
  • BarcodeFormat.PDF_417
  • BarcodeFormat.DATA_MATRIX

Barcode additional params:#

  /// With this option, the scanner assumes that the barcode can be a GS1 barcode, and modifies the behavior as needed.  /// You can set it to FALSE, if you don't want to see decoded FNC1 characters ("]C1" and ASCII char 29).  /// The default is TRUE.  bool? enableGS1Decoding;
  /// Minimum required text length of the detected barcode.  /// The default is 0.  /// NOTE: Currently works for ITF barcodes only!  int? minimumTextLength;
  /// Maximum text length of the detected barcode. Setting to zero removes the limit.  /// The default is 0.  /// NOTE: Currently works for ITF barcodes only!  int? maximumTextLength;
  /// Minimum required quiet zone on the barcode. Measured in modules (the size of minimal bar on the barcode).  /// The default is 10.  /// NOTE: Currently works for ITF barcodes only!  int? minimum1DBarcodesQuietZone;

Handle Encrypted Images#

Display Encrypted Images

If the file encryption is enabled you will not be able to display preview images via file URIs (e.g. page.documentPreviewImageFileUri). Instead, you have to load the decrypted data of a preview image and use it for displaying an image. In order to do that there is the API function getDecryptedDataFromFile(imageFileUri: string):

Page page = ... // scanned page object// use the low-res image "documentPreviewImageFileUri" for the preview:var decryptedImageData = await ScanbotEncryptionHandler.getDecryptedDataFromFile(page.documentPreviewImageFileUri);Image image = Image.memory(decryptedImageData); //use image widget to show preview

๐Ÿ‘‰ For a full implementation see our example app.

Upload Encrypted Images

To upload an image you have the following options:

1) Use the encrypted image file to upload to your server and decrypt it in the backend. Please contact our team to get support on how to generate the corresponding AES key and decrypt images on your backend.

2) Or alternatively, get the decrypted image data as Base64 on the mobile device by using the getDecryptedDataFromFile(imageFileUri: Uri) function and use this data for the upload process:

Examples:

// For a Page image file:Page page = ... // scanned page object// use the final hi-res image "documentImageFileUri" for the upload process:var decryptedImageData = await ScanbotEncryptionHandler.getDecryptedDataFromFile(page.documentImageFileUri);yourCustomUploadFunction(decryptedImageData);
// For a PDF or TIFF file generated by the Scanbot SDK:Uri fileUri = ... // Uri of the generated PDF or TIFF filevar decryptedFileData = await ScanbotEncryptionHandler.getDecryptedDataFromFile(fileUri);yourCustomUploadFunction(decryptedFileData);

Building Production Apps#

iOS#

The Scanbot Barcode Scanner SDK iOS Framework (included in this Flutter Plugin) contains the most used architectures (arm64, armv7, x86_64, i386). You can thus run it on all commonly used iOS devices as well as on simulators during the development phase. To be able to submit a production build to the App Store or a test build for TestFlight you have to remove (strip away) the architectures x86_64 and i386 from the Scanbot Barcode Scanner SDK Framework. These architectures are only for simulators and not allowed to be submitted to iTunes Connect.

Android#

The Scanbot Android SDK uses native libraries under the hood and supports the following ABIs: armeabi-v7a, arm64-v8a, x86 and x86_64.

By default the native libraries of all these architectures will be included in the app package (APK), which will result in a larger APK file. Please consider removing support for x86 and x86_64 architectures. In most cases both "x86" architectures can be removed for the release (production) build, since they are only used on emulators and on some rare devices with the Intel Atom architecture.

To exclude certain ABIs from the APK, use the abiFilters property in the android/app/build.gradle file of your project:

android {  ...  defaultConfig {    ...    ndk {      abiFilters "armeabi-v7a", "arm64-v8a"        // Please add "x86" and "x86_64" if you would like to test on an emulator        // or if you need to support some rare devices with the Intel Atom architecture.    }  }}

In this example we defined abiFilters for armeabi-v7a and arm64-v8a, so x86 and x86_64 architectures will be excluded.

info

However, if you need to support all architectures and would also like to optimize the APK size, we highly recommend checking out the Android App Bundle approach. It allows you to create and distribute dedicated, smaller APKs via the PlayStore (basically, it is similar to the iOS App Store approach).