cScanTWAIN - version 
Looking for
version 2,
version 3,
version 4
What's New
Version 5.2
- Improved socket support
- New cscanConfig property: CSCAN_USE_INI
- Fixed application freeze attempting display scanner dialog running as a Windows Service
- Domain .localhost now included
- Other optimizations and improvements
Version 5
- SDK file naming now includes version reference (ie: _v5)
- Sockets are now wrapped in Javascript promises
- New callback to send base64 to the front-end client after all scanning has completed
- MODE 1 and MODE 2 have been separated for clarity and resource reduction
- PDF support has been enhanced with full document delivery as base64 instead of by page
- PDF support has been enhanced to allow page deletes from an imported multi-page PDF
- Enhanced user experience with refreshed MODE 1 dialog
- Additional color schemes
- Other optimizations and improvements
GUIDE
Sample File Structure
This is not a requirement but just a reference of how you might organize your code files.
/public
/lib
/cScanTWAIN
You only need the css file with the color profile you want or you can use them as a template to create your own.
cscan_cantaloupe_v5.min.css
cscan_nickel_v5.min.css
cscan_orchid_v5.min.css
cscan_sky_v5.min.css
cscan_tungsten_v5.min.css
This is the configuration file and is required.
cscanConfig_v5.2.js
You only need the file for the mode you wish to use.
cscan_mode1_v5.2.trial.min.js // Development
cscan_mode2_v5.2.trial.min.js // Development
cscan_mode1_v5.2.min.js // Production
cscan_mode2_v5.2.min.js // Production
The pdf files are for MODE 1 and are not required for MODE 2.
pdf-lib.min.js
pdf.min.js
pdf.worker.min.js
Include the cScanTWAIN executable if you want to allow users to download the companion application.
Reference CSCAN_DOWNLOAD_LINK configuration for more detail.
cScanTWAIN_v5.2.exe
cScanTWAIN consists of only a few files that need to be included in the HTML document. Basic understanding of HTML and CSS is a pre-requisite, so this should need little explanation. Somewhere
you will need to call the Javascript function for the mode you are using
csharks1.acquire(); or
csharks2.acquire();
Easy Integration with a few lines of Code
<html>
<head>
<link rel="stylesheet"
href="/lib/cScan/cscan_sky_v5.min.css"/>
</head>
<body>
<button onclick="scanSomething()">SCAN</button>
<script
src="/lib/cScan/pdf-lib.min.js" type="module"></script>
<script
src="/lib/cScan/pdf.min.js" type="module"></script>
<script
src="/lib/cScan/cscanConfig_v5.2.js"></script>
<script
src="/lib/cScan/cscan_mode1_v5.2.min.js"></script>
<script>
function scanSomething() {
csharks1.acquire();
}
</script>
</body>
</html>
ORDER OF INCLUSION
Make sure the configuration file "cscanConfig_v5.js" is included before cscan_mode1_v5.min.js, so that it can be confidently accessed by the component, and place the CSS at the top in the HEAD
section of your HTML.
PDF SUPPORT FILES
Do not include pdf.worker.min.js because it is dynamically loaded but PDF js files must be in the same directory.
Support for client side PDF is provided by the
Mozilla PDF.js and
PDF-LIB projects.
Companion Application
The
cScanTWAIN_v5.2.exe companion application represents a small 32-bit Windows executable that is non-intrusive and generally does not require any special installation routines or
administrative privileges. It is required and acts as a bridge between the web application and TWAIN compliant scanner. The executable must be on the client PC and can be in any
directory, so long as it can be executed by the user.
RUN AS AN APPLICATION
cScanTWAIN_v5.2.exe is a simple application and when executed will place a small icon in the system tray.
This works great for those with little Windows knowledge or IT support and when there is a single user that will login at a given time. Sometimes it may be preferable to put a
shortcut to the companion application into the users startup folder, or create a desktop shortcut making it easier for the user to find and execute.
RUN AS A WINDOWS SERVICE
(may require administrative privileges)
If you wish to install cScanTWAIN as a Windows Service then use the "--service" argument. This may be a good choice when more than one user logs into the same workstation using the
Windows "switch user" feature.
*** Avoid when using MODE 2 ***
Windows Service applications do not have a user interface and therefore running cScanTWAIN as a Service cannot display user interface dialogs from within the application. If using MODE 1 and a scanner profile attempts to show the scanner default dialog (ie: UI: true) then that setting will be ignored.
To install and run as a Windows service, get to a terminal window command prompt and issue the following commands using the Service Control Manager (SCM):
sc create cScanTWAIN binPath="c:\YourPathToEXE\cScanTWAIN_v5.2.exe --service"
sc start cScanTWAIN
sc stop cScanTWAIN
To Delete the Service:
sc delete cScanTWAIN
Configuration
Configuration settings are in the cscanConfig_v5.2.js file.
LICENSE_KEY
Description: Domain registered license key.
The license key will be provided upon successful purchase of our SDK. You are free to download, implement, and demo the TRIAL SDK for as long as you wish
without restrictions. However, without a valid license key then a watermark will appear on each scanned image obtained by our SDK.
CSCAN_DOWNLOAD_LINK
Description: Show a download link to the cScanTWAIN_v5.2.exe companion application for distribution.
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js if you are not using it.
Example: "/lib/cScan/cScanTWAIN_v5.2.exe"
If used then the cScanTWAIN_v5.2.exe file must be on your web server where it is accessible using the defined link.
CSCAN_ADMIN_NOTICE
Description: Show a notice of information.
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js if you are not using it.
Example: “If you need assistance then please contact your system administrator”
CSCAN_PORT
Description: The port that the cScanTWAIN_.2.exe companion application should listen on.
Default: 26813
This normally does not need to be changed
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js when you are using default value.
Notes: This is only required if you experience a port conflict. If changing from the default port 26813 then the cScanTWAIN_v5.2.exe
companion application must be executed with an argument to specify the alternate port. This is global to all cScanTWAIN_vnnn.exe users, so take careful consideration when
deciding to use a different port value. --port=nnnnn
Example: cScanTWAIN.exe --port=25155
CSCAN_FILETYPE
Description: Represents the type of base64 data that will be returned.
Allowed Values: [PDF, JPEG] default=PDF
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js if you are using the default value.
MODE 1
The cScanTWAIN dialog is an out-of-the-box user interface that receives the scanned image. When used without showing the default scanner user dialog then the developer maintains
control over what scanner settings are allowed by the user. In this mode the cScanTWAIN dialog incorporates a simple image viewer including a few options, such as flip and delete,
as well as a PDF import (if implemented), and the upload to server functional operation.
This mode can send the base64 data to a URL or to your front-end depending on your configuration settings. Please reference CSCAN_UPLOAD_URL further down in this guide.
This mode supports TWAIN and sometimes WIA depending on the manufacturers implementation, and when selecting a WIA source device, the settings implied by all Mode 1 configurations may not
apply as one would expect. This is because WIA is not actually TWAIN and WIA devices are defined for use with the Windows Imaging Acquisition API, which at this time cScanTWAIN
operates in a TWAIN compliant manner.
Mode 1 also supports the use of the scanners default dialog by using the "UI" parameter in the scanner profiles. Regardless of which mode is used, anytime the scanner default
dialogs are used then the user will have the most control over the scanner settings as possible.
MODE 2
The scanner default dialog will be used and the cScanTWAIN dialog will be suppressed. Scanned images acquired by the scanner will be returned via a callback that the developer must
implement. Only an occasional "flash" message may be displayed to provide status updates.
This mode may support both TWAIN and WIA depending on the manufacturers implementation and regardless of which mode is used, anytime the scanner default dialogs are used then the user will
have the most control over the scanner settings as possible.
In this mode the developer is responsible for implementing the callback function cScanTWAIN_OnAcquireImage(base64Data) that receives the base64 data..
You normally would
not create this callback function unless you are using MODE 2 but regardless of which mode you implement, if this callback function is defined in your javascript then
it will be called.`
Example:
This callback will receive the base64 data after each scan is acquired by the scanning device
function cScanTWAIN_OnAcquireImage(base64Data) {
console.log(base64Data);
}
Depending on your CSCAN_FILETYPE setting here is an extract of the base64 data returned by cScanTWAIN:
JPEG: /9j/4AAQSkZJRgABAQEAyADIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJ...
PDF: JVBERi0xLjcKJYGBgYEKCjggMCBvYmoKPDw...
Reference: Sample code snippets that receive the base64 data via the callback.
//
// If you are expecting PDF data, CSCAN_FILETYPE: "PDF" (default=PDF)
//
const base64ToArrayBuffer = (_base64Str) => {
let binaryString = window.atob(_base64Str);
let binaryLen = binaryString.length;
let bytes = new Uint8Array(binaryLen);
for (let i = 0; i < binaryLen; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
function cScanTWAIN_OnAcquireImage(base64Data) {
//
// If you are expecting PDF data, CSCAN_FILETYPE: "PDF" (default=PDF)
//
let byte = base64ToArrayBuffer(response);
let blob = new Blob([byte], {type: "application/pdf"});
window.open(URL.createObjectURL(blob), "_blank");
//
// If you are expecting JPEG data, CSCAN_FILETYPE: "JPEG"
//
let elem = document.createElement(“img”);
elem.src = “data:image/jpeg;base64,” + base64Data;
document.body.appendChild(elem);
}
Mode 1 Configuration
CSCAN_UPLOAD_URL
Description: URL where the base64 data will be uploaded via a multipart form POST request. Change this to match your upload destination
URL. This can also be commented/removed if you are wanting to implement the cScanTWAIN_OnUploadToClient(base64Data) callback function. Please reference the OVERRIDE and
CALLBACKS section of the guide.
Recommendation: Instead of duplicating backend upload code for different documents, create a generic upload backend and override
CSHARKS.CSCAN_UPLOAD_PREFIX within your javascript, so that your backend can easily identify what is being uploaded.
CSCAN_HEADERS
Description: Post header object
Recommendation: Comment/Remove from your cscanConfig_v5.2.js if you are not using it.
This is a Javascript Object Representing the Headers to send with the Fetch API call. cScanTWAIN utilizes the Javascript Fetch API for uploading and if this directive is set then it
will be sent in the headers object. May be useful for sending to a third party backend storage such as Amazon S3.
Example: CSHARKS.CSCAN_HEADERS = { Authentication: "Bearer Token" }
According to the Fetch API documentation, the following are the forbidden Fetch API header names.
Content-Length
Host
Referer
Access-Control-Request-Headers
Access-Control-Request-Method
CSCAN_UPLOAD_PREFIX
Description: Prefix applied to the uploaded file POST variable filenames.
Default: "CSCANTWAIN_"
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js if you are using the default.
File Naming Convention: CSHARKS.CSCAN_UPLOAD_PREFIX + "cscanData_p" + pageNumber
Example POST request: CSCANTWAIN_cscanData_p1
CSCAN_UPLOAD_IMMEDIATELY
Description: Upload the image immediately after it is acquired.
Allowed Values: [true, false] default=false
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js when using the default value.
Uploads will occur immediately after a scan operation has completed. If you set this to TRUE then you will likely use the default
setting for CSCAN_DELETE_AFTER_UPLOAD to prevent the user from inadvertently uploading the same scan more than once. This setting does
not apply to PDF imports.
CSCAN_DELETE_AFTER_UPLOAD
Description: Delete Scanned Images from the cScanTWAIN dialog after upload is complete.
Allowed Values: [true, false] default=true
Recommendation: Remove this from your cscanConfig_v5.2.js when using the default value.
CSCAN_CLOSE_AFTER_UPLOAD
Description: Automatically close the cScanTWAIN dialog after the upload is complete.
Allowed Values: [true, false] default=true
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js when using the default value.
Note: All images are removed from the cScanTWAIN dialog whenever it is closed.
CSCAN_UPLOAD_MAX_PAGES
Description: Max pages allowed to upload
Allowed Values: [Integer, -1=Unlimited]
Recommendation: Setting this value to match your use case requirements will help mitigate unnecessary resource consumption. Comment/Remove if using the default value.
Attempts to upload more than this threshold will result in a warning error and the base64 data will not be sent.
Note: Your server may have payload size and memory restrictions and should be adjusted for your expected max upload constraints. If your server is
not properly configured to accept the payload size of the uploaded documents, you may notice that the client (browser) returns a successful upload response but the server did not
accept your files.
Reference: In PHP the server payload restrictions would be found in the php.ini configuration:
post_max_size
memory_limit
upload_max_filesize
CSCAN_IMPORTPDF
Description: Allow importing of an external PDF document
Allowed Values: [true, false] default=true
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js when using the default value.
CSCAN_USE_INI
Description: Instructs the client side .EXE to preserve the last selected scanner selection into an .ini file
This is useful in cases where the users browser cache and Local Storage are automatically cleared and are no longer persistent. User this optino does require that the EXE can write the ini to the installation directory.
Allowed Values: [true, false] default=false
Recommendation: Comment/Remove this from your cscanConfig_v5.2.js when using the default value.
CSCAN_PROFILES
Description: Scanner profiles represent desired scanner settings for different types of documents that you expect to be scanned.
If no profiles are defined then CSCAN_PROFILES must be commented/removed from the cscanConfig_v5.2.js file and a default profile of Black and White 200 DPI will be used. It is possible to pass a scanner profile during the call
to csharks1.acquire(profileNumber) with the profileNumber representing the profile you wish to have automatically selected. When passing a profile then scanning will begin without
the user having to hit the scan button found on the cScanTWAIN dialog.
Example: Profile configurations are zero based, so using the sample profiles below we can pass a value of '1' to use the Color Document profile: csharks1.acquire(1);
Reference: Sample profiles
In the below sample you will notice two different Driver's License profiles that were provided to illustrate different PIXEL, DPI, CROP and THRESHOLD parameters. These two profiles
will return essentially the same region of the document but take notice of the different CROP parameters. This is because a 300 DPI document contains more pixels than a 200 DPI
document.
CSCAN_PROFILES: [
{"NAME": "B/W Document Sample"},
{"NAME": "Color Document Sample", "PIXEL": 2},
{"NAME": "Driver's License 200 DPI Sample", "CROP": "0, 0, 650, 400", "THRESHOLD": 120},
{"NAME": "Driver's License 300 DPI Sample", "PIXEL": 1, "DPI": 300, "CROP": "0, 0, 975, 600"},
{"NAME": "Grayscale Sample", "PIXEL": 1},
{"NAME": "Show Scanner UI Sample", "PIXEL": 2, "UI": true},
{"NAME": "Brightness & Contrast Sample", "BC": "800, -250"}
{"NAME": "Simple Duplex Scan", "DUPLEX": true"}
]
PROFILE PARAMETERS
Profiles consist of parameters that can be assigned to achieve your desired scan result. All profiles have a default value and when the default value is desired then there is no
requirement to include that parameter.
Recommendation: All profile parameters have a default value and when the default value is used then do not include that parameter. Simply
leave it off.
When using the "UI" parameter and allowing the scanners default dialog to be shown, then your parameters act only as a starting point for the scanner settings. The user will have full
control over the scanner settings when using the scanner default dialog.
PIXEL
Description: The pixel type.
Allowed Values: [0, 1, 2] default=0 (0=Black and White, 1=Grayscale, 2=Color)
Black and White typically yields the smallest resulting file size and you should set this according to your use case requirements. For example you may find that a grayscale image
results in a larger file size than a color image. This is due to the amount of compression that can be achieved for different color ranges. You will want to experiment with these
settings based on the documents that will be scanned and your desired output requirements.
DPI
Allowed Values: Values supported by the scanner.
Typical values: [300, 200, 150, 100] default=200
Recommendation: DPI of 200 is a good starting choice for quality vs file size and is generally supported by all scanners.
Note: If your scanner does not support the value specified then it will use its own default value.
Higher DPI results in better quality but may produce larger file sizes, so set this according to your use case requirements.
Sampling a full page 8x11 black and white document returned as PDF using different DPI settings. 300=42k, 200=31k, 150=25k
UI
Description: Wether or not to show the scanners own default user interface.
Allowed Values: [true, false] default=false
Note: Showing the scanners default dialog provides the user with the most control over the scanner settings.
DUPLEX
Description: Use duplex scanning
Allowed Values: [true, false] default=false
Note: If the scanner does not support duplex scanning then this setting should have no impact.
CROP
Description: This is the cropping region in pixels to be returned from the scanned document.
Represents: Top, Left, Right, Bottom
Recommendation: If no cropping desired then do not include this parameter.
Note: If "UI": true then no cropping will be performed.
This tool may be of use determining your cropping values:
Pixel Calculator
BC
Description: Brightness and contrast.
Allowed Values: [-1000..1000, -1000...1000] default=0, 0
Recommendation: Most modern scanners manage this automatically and therefore this parameter rarely needs to be used.
THRESHOLD
Description: Intensity value for black and white documentsl. Levels less than THRESHOLD are set to black and the reminder to white.
Allowed Values: [0..255] default=175
Note: Only applies to Black and White documents (ie: PIXEL = 0)
In the profile samples above you can see that the "200 DPI Drivers' License" profile uses a threshold of 120 which enhances the conversion of a colored background license into
a 1 bit black and white image. As an example, certain colors in the red spectrum may be impacted by this value and could end up faded or simply removed from the document.
Depending on your use case requirements then you may want to experiment with this value.
Javascript Override and Callback
cScanTWAIN overrides are useful for changing configuration properties. As in this example we could have different configurations from what is already set in the cscanConfig_v5.2.js
file. You can easily override this from within your pages Javascript. Below we are using a different upload prefix.
OVERRIDE
These are usually best done in the DOMContentLoaded event.
Override for accounting documents
document.addEventListener("DOMContentLoaded", (event) => {
CSHARKS.CSCAN_UPLOAD_PREFIX: "ACCOUNTING_",
});
CALLBACK
If you have defined a callback function in your javascript then it will be called by cScanTWAIN.
The next two callbacks will usually not be used together. This function receives the base64 encoded data after each page is
scanned by the device.
function cScanTWAIN_OnAcquireImage(base64data) {
console.log(base64data);
}
This function will only be called if you do not specify a CSCAN_UPLOAD_URL and will receive either the full PDF base64 document data, or each
JPEG base64 data until all are sent. PDF documents can be multi-page and therefore this function will only receive a single base64 dataset
representing the entire PDF document. JPEG however does not support the concept of multi-page and therefore are sent as individual base64 data.
function cScanTWAIN_OnUploadToClient(base64data) {
console.log(base64data);
}
This function is called when the dialog is closed.
function cScanTWAIN_OnDialogClosed() {
console.log("Dialog has closed");
}
If you are using a URL destination for the base64 data then this function will be called and receives the JSON response that is returned by your backend server.
At a minimum your backend code must return '{ "status":"Success" }' so please reference the sample server side PHP code
In our demo we return: '{ "status":"Success", "fileName" : "' . $baseFileName . '" }'
function cScanTWAIN_OnUploadComplete(response) {
console.log(response);
let obj = JSON.parse(response);
console.log("Upload completed: " . obj.fileName);
}
Sample Server Side PHP Code
You should be able to gleam enough intelligence from these code snippets to jump start your efforts.
Uploading the base64 encoded data to the backend server is generally straight forward. Scanned images are sent using the POST method as base64 encoded files
within a multipart form. This should be easily adaptable to most backend web development languages and frameworks. You probably want to handle error
conditions that may occur server side.
Lets take a look at a var_dump of the $_POST variable from our backend code. The string value will be either base64 encoded PDF or JPEG depending on your
CSCAN_FILETYPE configuration. Lets assume that we have scanned two pages.
var_dump($_POST);
PDF
array(1) {
["DEMO_cscanData_p1"]=> string(278645) JVBERi0xLjcKJYGBgYEKCjggMCBvYmoKPDw...”
}
JPEG
array(2) {
["DEMO_cscanData_p1"]=> string(134324) /9j/4AAQSkZJRgABAQEAyADIAAD/2wBDAAYEBQY...
["DEMO_cscanData_p2"]=> string(141056) /9j/4AAQSkZJRgABAQEAyADIAAD/2wBDAAYEBQY...
}
PDF is delivered as a single document. JPEG however does not support the concept of multi-page there for
each base64 data image is delivered.
CSCAN_FILETYPE: "PDF" or "JPEG"
In this sample we are demonstrating code that accepts base64 encoded data for both PDF or JPEG. You can build support
for both format types or implement just the code required for your expected format.
$uploadDir = 'ThePathToYourDesiredDestination';
// Here we have decided to extract the uploaded filename prefix (see cscanConfig.js CSCAN_UPLOAD_PREFIX: "DEMO_")
$namePrefix = isset($_POST) ? substr(key($_POST), 0, strpos(key($_POST), '_')) : 'Unknown';
$baseFileName = $namePrefix . '_' . date('YmHis');
$outputFileName = $uploadDir . $baseFileName;
// Examine the first $_POST variable to determine if we have PDF or JPEG
$fileExtension = str_starts_with(base64_decode($_POST[array_key_first($_POST)]), '%PDF') ? '.pdf' : '.jpg';
foreach ($_POST as $k => $v) {
$pageNo = (int)filter_var($k, FILTER_SANITIZE_NUMBER_INT);
$decodedData = base64_decode($v); // PDF or JPEG
file_put_contents($outputFileName . '_p' . $pageNo . $fileExtension, $decodedData);
}
echo '{ "status":"Success", "fileName" : "' . $baseFileName . '" }';
Hints & Troubleshooting
Flipping an already flipped imported PDF
In an instance where you import an already flipped PDF, essentially implying that it is upside down, then flipping the
page may appear correct in the viewer but then final uploaded PDF does not conform and reverts back to its original
state. However, if you flip the page a few times then the final uploaded PDF will conform. This
is an issue in the PDF-JS library where it makes an assumption on the state of the PDF during its first flip iteration. We
will continue to monitor their github issues tracker.
PDF size grows when importing multi-page PDF document
You may notice that when importing a multi-page PDF that the resulting PDF is sometimes larger than expected. In most cases the size
is insignificant and is noticed when importing a large multi-page PDF. This is caused by the PDF-JS library and we will
continue to monitor their github issue tracker.
Windows Firewall
Windows may block the execution of the cScanTWAIN EXE companion application . Provided this setting works with your deployment, it is our recommendation
to only allow your private network. The cScanTWAIN EXE companion application only needs to communicate with the browser from the localhost and does
not need access to the internet. Please consult with your System Administrator.
Security with CORS (Cross-Origin Resource Sharing) and the Companion Application
The default is for the cScanTWAIN EXE companion application to allow only localhost origin and honors only specific request types. It will not respond
to other requests, forged or
otherwise, and specifically works as a bridge between your web application and your TWAIN device.
TWAIN Compliant Scanner
We have used the most basic scanner settings possible to cover a broad range of devices. Most modern scanners should work without issue but if you
run across a specific problem then we would like to hear about it.
Customizing the Viewer
This can be done by overriding the basic CSS with your own CSS file. Our recommendation is to duplicate one of the provided css files and modify it to
meet your requirements.
HAPPY SCANNING...
Download a Trial