Document Scan
The Docutain Document Scanner SDK for Android comes with integrated, ready to use UI components for the document scan process. Colors and icons can be changed to match your branding.
It is also possible to use the Document Scanner on imported images.
Initialization
Make sure you have defined the following package dependencies in your app's build.gradle
file:
def docutainSdkVersion = '1.7.0.3'
//For Document Scanner components
implementation("de.docutain:Docutain-SDK-UI:$docutainSdkVersion")
Initialize the Docutain Android Scanner SDK as described here.
Scan with Camera
Camera Permission
Declare permissions to use the camera in your AndroidManifest.xml
:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
Runtime permission for camera is handled automatically by the Docutain SDK.
Start Camera Scan
To start the scan process you only have to launch an ActivityResultLauncher
with our predefined ScanResult
contract and wait for it to return.
An instance of DocumentScannerConfiguration
is required to launch the document scanner. It provides the possibility to change some behaviours to adopt it to your needs.
See Change default scan behaviour for possible custom settings.
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result ->
if(result){
//user finished scan process, continue with your workflow
//generate PDF by using Document.writePDF()
//get detected Text by using DocumentDataReader.getText()
//get data by using DocumentDataReader.analyze()
} else{
//user canceled scan process
}
}
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
if(result){
//user finished scan process, continue with your workflow
//generate PDF by using Document.writePDF()
//get detected Text by using DocumentDataReader.getText()
//get data by using DocumentDataReader.analyze()
} else{
//user canceled scan process
}
}
});
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
documentScanResult.launch(scanConfig);
}
});
Scan from imported images
It is also possible to use the Document Scanner on already taken images, for example images selected from the users photo gallery. The process of starting the scanner on imported images is the same as when scanning with the camera.
The only difference is defining a different source
in the DocumentScannerConfiguration
. Possible values are:
CAMERA
: This is the default value. Starts the Document Scanner using the devices camera.IMAGE
: Starts the Document Scanner on images provided by you via code. PasssourceImages
to theDocumentScannerConfiguration
containing the paths to the images to be scanned.GALLERY
: Opens the user's photo gallery in single select mode. The Document Scanner is run on the selected image.GALLERY_MULTIPLE
: Opens the user's photo gallery in multi select mode. The Document Scanner is run on the selected images.
The following sample shows how to open the photo gallery in multi select mode and run the Document Scanner on the selected images:
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result ->
if(result){
//user finished scan process, continue with your workflow
//generate PDF by using Document.writePDF()
//get detected Text by using DocumentDataReader.getText()
//get data by using DocumentDataReader.analyze()
} else{
//user canceled scan process
}
}
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.source = Source.GALLERY_MULTIPLE
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
if(result){
//user finished scan process, continue with your workflow
//generate PDF by using Document.writePDF()
//get detected Text by using DocumentDataReader.getText()
//get data by using DocumentDataReader.analyze()
} else{
//user canceled scan process
}
}
});
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.setSource(Source.GALLERY_MULTIPLE);
documentScanResult.launch(scanConfig);
}
});
Change default scan behaviour
DocumentScannerConfiguration
You can use the DocumentScannerConfiguration
to alter the default scan behaviour to your needs. Currently the following values can be set:
Property | Type | Default Value | Description |
---|---|---|---|
allowCaptureModeSetting | Boolean | false | If true, the document scanner toolbar will display an item that allows the user to switch between automatic and manual camera triggering. |
autoCapture | Boolean | true | If true, the camera will capture the image automatically at the right moment. |
defaultScanFilter | ScanFilter | ILLUSTRATION | The default scan filter that will be used after scan. |
onboardingImageSource | Int | R.drawable.hint_edge_detection | Your custom image for the onboarding dialog that appears when scan is opened for the first time. |
pageEditConfig | PageEditConfiguration | PageEditConfiguration | Configuration class used to alter the default page editing behaviour. See PageEditConfiguration for more details. |
source | Source | CAMERA | The source of the Document Scanner. If you need to run the scanner on imported images please see Scan from imported images for more details. |
sourceImages | List<java.io.File> | empty list | Please see Scan from imported images for more details. |
autoCrop | Boolean | true | If true, image gets automatically cropped if document was detected. This applies only when importing images. |
multiPage | Boolean | true | If true, scanning multi page documents is possible. Set this to false if you need to scan single page documents. |
preCaptureFocus | Boolean | true | If true, the camera will run a focus action right before taking the image. This improves the quality of the scanned images, but depending on the device, image capture might take a little bit longer. |
theme | Int | R.style.DocutainSDK_Theme_Default | Your custom theme if you like to change colors to match your branding. Please see ColorConfiguration for more details. |
textConfig | TextConfiguration | TextConfiguration | Configuration class used to alter the default text behaviour. See TextConfiguration for more details. |
buttonConfig | ButtonConfiguration | ButtonConfiguration | Configuration class used to alter the default buttons. See ButtonConfiguration for more details. |
confirmPages | Boolean | false | If true, a list of all pages (thumbnails) will be displayed before the scan process can be finished. |
allowPageEditing | Boolean | true | If true, after the scan screen is finished, an editing screen with the captured images will be displayed. On the editing screen, the user can crop manually, rotate the page, filter the page and much more. The editing screen can be configured by accessing the PageEditConfiguration . |
All parameters in DocumentScannerConfiguration
are optional.
The following sample shows how to activate the confirmation mode:
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result -> }
...
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.confirmPages = true
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() { });
...
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.setConfirmPages(true);
documentScanResult.launch(scanConfig);
}
});
PageEditConfiguration
You can use the PageEditConfiguration
to alter the default page editing behaviour of the document scanner to your needs. Currently the following values can be set:
Property | Type | Default Value | Description |
---|---|---|---|
allowPageFilter | Boolean | true | If false, the bottom toolbar will hide the filter page item. |
allowPageRotation | Boolean | true | If false, the bottom toolbar will hide the rotate page item. |
allowPageArrangement | Boolean | true | If false, the bottom toolbar will hide the arrange page item. |
allowPageCropping | Boolean | true | If false, the bottom toolbar will hide the page cropping item. |
allowPageRetake | Boolean | false | If true, the bottom toolbar will show a button allowing to retake the current page. |
pageArrangementShowDeleteButton | Boolean | false | If true, each item of the page arrangement functionality will show a delete button. |
pageArrangementShowPageNumber | Boolean | true | If true, each item of the page arrangement functionality will show it's page number. |
All parameters in PageEditConfiguration
are optional.
The following sample shows how to activate the page retake button:
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result -> }
...
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.pageEditConfig.allowPageRetake = true
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() { });
...
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.getPageEditConfig().setAllowPageRetake(true);
documentScanResult.launch(scanConfig);
}
});
TextConfiguration
You can use the TextConfiguration
to alter the default text behaviour of the document scanner to your needs. If a value does not get set explicitly, the default value provided by the SDK will be used. If you set a text value to null, it won't show any text. You can use this to remove predefined text. Currently the following values can be set:
Property | Type | Description |
---|---|---|
textSizeBottomToolbar | Float? | The text size of elements residing in the bottom toolbar. |
textSizeTopToolbar | Float? | The text size of menu items residing in the top toolbar. |
textSizeScanButtons | Float? | The text size of the buttons in the scan page, located at the lower part, like the torch button. |
textSizeTitle | Float? | The text size of the title in the top toolbar. By default, auto shrinking down till 9.0 is enabled. If you define your custom size, automatic shrinking will be disabled. |
textTitleScanPage | String? | The title to be displayed in the scan page top toolbar. |
textTitleEditPage | String? | The title to be displayed in the edit page top toolbar. |
textTitleFilterPage | String? | The title to be displayed in the filter page top toolbar. |
textTitleCroppingPage | String? | The title to be displayed in the cropping page top toolbar. |
textTitleArrangementPage | String? | The title to be displayed in the page arrangement page top toolbar. |
textTitleConfirmationPage | String? | The title to be displayed in the confirmation page top toolbar. |
textDocumentTitle | String? | The title to show in the top toolbar on all pages. It overwrites page specific titles, if any are set. |
textOnboardingTitle | String? | The text to show in the onboarding popup title that appears when the scan page is opened for the first time. |
textOnboardingMessage | String? | The text to show in the onboarding popup message that appears when the scan page is opened for the first time. |
textOnboardingCloseButton | String? | The text to show in the onboarding popup close button that appears when the scan page is opened for the first time. |
textSizeOnboardingTitle | Float? | The text size of the onboarding popup title that appears when the scan page is opened for the first time. |
textSizeOnboardingMessage | Float? | The text size of the onboarding popup message that appears when the scan page is opened for the first time. |
textFocusHint | String? | The text to show when camera is focusing after capture got triggered. |
textFirstPageHint | String? | The text to show when user swipes to previous page but is already at the first page. |
textLastPageHint | String? | The text to show when user swipes to next page but is already at the last page. |
textOnePageHint | String? | The text to show when user swipes to next or previous page but only one page is available. |
textScanProgress | String? | The text to show in the progress popup that is shown when user clicks the done button but some pages still need to be processed. |
textDeleteDialogCurrentPage | String | The text to show for the option to delete the current page within the dialog that will be shown when clicking delete while multiple pages are available. |
textDeleteDialogAllPages | String | The text to show for the option to delete all pages within the dialog that will be shown when clicking delete while multiple pages are available. |
textDeleteDialogCancel | String? | The text to show for the option to cancel within the dialog that will be shown when clicking delete while multiple pages are available. |
All parameters in TextConfiguration
are optional.
The following sample shows how to set a document title:
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result -> }
...
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.textConfig.textDocumentTitle = "Custom Document Title"
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() { });
...
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.getTextConfig().setTextDocumentTitle("Custom Document Title");
documentScanResult.launch(scanConfig);
}
});
ButtonConfiguration
You can use the ButtonConfiguration
to alter the default buttons of the scanner. Each button is an object of DocutainButton
and has a title
and icon
property.
Buttons residing in the top toolbar can have either a title or an icon. If you define both, the icon will be displayed. Buttons residing in the bottom toolbar can have both title and icon at the same time. If you want a button to only display text, set the icon
property to null and the title
property to the text you want to display. If you want a button to only display an icon, set the title
property to null and the icon
property to the icon you want to display.
Currently the following buttons can be set:
Button | Default Value | Description |
---|---|---|
buttonEditRotate | The button that rotates the current page. | |
buttonEditCrop | The button that opens the cropping functionality. | |
buttonEditFilter | The button that opens the filter functionality. | |
buttonEditArrange | The button that opens the page arrangement functionality. | |
buttonEditRetake | The button that starts the process of replacing the current page with a new scan. | |
buttonEditDelete | The button that deletes the current page or opens a dialog with options if multiple pages are available. | |
buttonEditFinish | The button that finishes the scan process. | |
buttonCropExpand | The button within the cropping functionality that expands the current cropping rectangle to the whole page. | |
buttonCropSnap | The button within the cropping functionality that snaps the current cropping rectangle to the detected document. | |
buttonCropFinish | The button within the cropping functionality that finishes the manual cropping process according to the current cropping rectangle. | |
buttonScanAutoCaptureOn | The button within the scan functionality that is shown when automatic capture is activated. | |
buttonScanAutoCaptureOff | The button within the scan functionality that is shown when automatic capture is deactivated. | |
buttonScanTorch | The button within the scan functionality that toggles the torch. | |
buttonScanCapture | The button within the scan functionality that triggers a manual image capture. | |
buttonScanFinish | The button within the scan functionality that finishes the current scan process and leads to the editing page. | |
buttonConfirmationFinish | The button on the confirmation page that finishes the scan process. |
All parameters in ButtonConfiguration
are optional.
The following sample shows how to customize the buttonEditRotate
:
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result -> }
...
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.buttonConfig.buttonEditRotate.title = "Custom Title"
scanConfig.buttonConfig.buttonEditRotate.icon = R.drawable.icon
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() { });
...
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.getButtonConfig().getButtonEditRotate().setTitle("Custom Title");
scanConfig.getButtonConfig().getButtonEditRotate().setIcon(R.drawable.icon);
documentScanResult.launch(scanConfig);
}
});
ColorConfiguration
In order to fit the Docutain Scanner SDK for Android into your corporate design, you have a bunch of options to alter the default color theming of the ready to use UI components.
Supported colors
The following is a list of all colors currently supported.
Color | Default Value | Description |
---|---|---|
docutain_colorPrimary | light: #4CAF50 dark: #4CAF50 | Used to tint progress indicators and dialog buttons. |
docutain_colorSecondary | light: #4CAF50 dark: #4CAF50 | Used to tint selectable controls and the capture button. |
docutain_colorOnSecondary | light: #FFFFFF dark: #000000 | Used to tint elements that reside on docutain_colorSecondary, like the icon of the capture button. |
docutain_colorScanButtonsLayoutBackground | light: #121212 dark: #121212 | Used to tint the background of the scan buttons layout. |
docutain_colorScanButtonsForeground | light: #FFFFFF dark: #FFFFFF | Used to tint the foreground of the scan buttons layout, like the torch button. |
docutain_colorScanPolygon | light: #4CAF50 dark: #4CAF50 | Used to tint the polygon overlay which highlights the currently detected document. |
docutain_colorBottomBarBackground | light: #FFFFFF dark: #212121 | Used to tint the bottom toolbar background of the image editing page. |
docutain_colorBottomBarForeground | light: #323232 dark: #BEBEBE | Used to tint the buttons within the bottom toolbar of the image editing page. |
docutain_colorTopBarBackground | light: #4CAF50 dark: #2a2a2a | Used to tint the top toolbar background. |
docutain_colorTopBarForeground | light: #FFFFFF dark: #DEFFFFFF | Used to tint the buttons contained in the top toolbar. |
docutain_colorTopBarTitle | light: #FFFFFF dark: #DEFFFFFF | Used to tint the text of the top toolbar title. |
Dark Mode
The Docutain Scanner SDK for Android also supports dark mode theming. The process is the same, just define different colors for the night version of your theme. The SDK decides which color to use depending on the device's sytem setting and it will change at runtime, if the device's display mode changes.
Defining a custom theme
In order to alter at least one of the colors mentioned above, you need to define a custom theme which uses DocutainSDK.Theme.Default
as parent.
The following is an example which alters all currently available colors.
<style name="DocutainSDKTestApp.DocutainSDKTheme" parent="DocutainSDK.Theme.Default">
<item name="docutain_colorPrimary">@color/colorPrimary</item>
<item name="docutain_colorSecondary">@color/colorSecondary</item>
<item name="docutain_colorOnSecondary">@color/colorOnSecondary</item>
<item name="docutain_colorScanButtonsLayoutBackground">@color/colorScanButtonsLayoutBackground</item>
<item name="docutain_colorScanButtonsForeground">@color/colorScanButtonsForeground</item>
<item name="docutain_colorScanPolygon">@color/colorScanPolygon</item>
<item name="docutain_colorBottomBarBackground">@color/colorBottomBarBackground</item>
<item name="docutain_colorBottomBarForeground">@color/colorBottomBarForeground</item>
<item name="docutain_colorTopBarBackground">@color/colorTopBarBackground</item>
<item name="docutain_colorTopBarForeground">@color/colorTopBarForeground</item>
<item name="docutain_colorTopBarTitle">@color/colorTopBarTitle</item>
</style>
To tell the scanner to use your custom theme, set the theme
attribute of the DocumentScannerConfiguration
.
- Kotlin
- Java
import de.docutain.sdk.ui.ScanResult
val documentScanResult = registerForActivityResult(ScanResult()) { result -> }
...
myButton.setOnClickListener {
val scanConfig = DocumentScannerConfiguration()
scanConfig.theme = R.style.your_custom_theme
documentScanResult.launch(scanConfig)
}
import de.docutain.sdk.ui.ScanResult
private ActivityResultLauncher documentScanResult = registerForActivityResult(new ScanResult(),
new ActivityResultCallback<Boolean>() { });
...
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentScannerConfiguration scanConfig = new DocumentScannerConfiguration();
scanConfig.setTheme(R.style.your_custom_theme);
documentScanResult.launch(scanConfig);
}
});
Result handling
After the scan process is successfully finished, you can do a bunch of things with the scanned pages:
Language Support
The device's locale determines the language used by the scanner.
The SDK provides default translations for certain languages. Refer to TextConfiguration if you want to set your own texts.
Currently available translations:
- English
- Arabic
- Bulgarian
- Chinese, Simplified
- Chinese, Traditional
- Croation
- Czech
- Danish
- Dutch
- Finnish
- French
- German
- Greek
- Hindi
- Hungarian
- Icelandic
- Indonesian
- Italian
- Japanese
- Korean
- Lithuanian
- Norwegian Bokmal
- Polish
- Portugese
- Portugese (Brazil)
- Romanian
- Russian
- Serbian
- Slovak
- Slovenian
- Spanish
- Swedish
- Turkish
The fallback language is English. This means if the device is set to a language that is currently not supported, it will show English texts.
If you think the translation can be improved, please feel free to contact us via support.sdk@Docutain.com.