Thanks for Downloading Dynamic Web TWAIN 30-Day Trial!
Your download will start shortly. If your download does not begin, click here to retry.
Dynamic Web TWAIN with Annotations – Hello World
Dynamsoft’s Dynamic Web TWAIN (DWT) is a software development kit (SDK) designed to integrate efficient document scanning workflows into web applications. Dynamsoft Document Viewer (DDV) is a versatile web document viewer with support for document annotations. In this guide, we explain how to use DDV in place of DWT’s built-in viewer to enable annotations and provide a superior viewer experience.
In this sample, we create a headless DWT instance to scan images, and then pass the result to DDV to view, edit, annotate, etc. We then use DWT to save the result - along with any edits and annotations - to a file, or upload to the server.

- Check out HelloWorld online
1. Add Dependencies
Use the SDK by including the packages below:
- Dynamic Web TWAIN: provides scanning, saving, and uploading functionalities.
- Dynamsoft Document Viewer: provides improved document viewer and annotation functionalities.
1.1 Deliver Dependencies via CDN
Deliver the SDK dependencies with either the jsDelivr or the UNPKG CDN.
-
jsDelivr
<!--Dynamic Web TWAIN--> <script src="https://cdn.jsdelivr.net/npm/dwt@19.2.0/dist/dynamsoft.webtwain.min.js"></script> <!--Dynamsoft Document Viewer--> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/ddv.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/ddv.css"> -
UNPKG
<!--Dynamic Web TWAIN--> <script src="https://unpkg.com/dwt@19.2.0/dist/dynamsoft.webtwain.min.js"></script> <!--Dynamsoft Document Viewer--> <script src="https://unpkg.com/dynamsoft-document-viewer@3.0.0/dist/ddv.js"></script> <link rel="stylesheet" href="https://unpkg.com/dynamsoft-document-viewer@3.0.0/dist/ddv.css">
2. Define HTML Elements
Define the following elements:
-
A container to hold the viewer
<div id="container" style="height:580px; width:1000px"></div> -
Buttons to invoke functions
<input type="button" value="Scan" onclick="AcquireImage();" /> <input type="button" value="Save PDF" onclick="SavePDF();" /> <input type="button" value="Upload" onclick="Upload();" />
3. Initialize the SDK
3.1 Initialize Dynamsoft Document Viewer
// Dynamsoft Document Viewer
// Public trial license which is valid for 24 hours
// You can request a 30-day trial key from https://www.dynamsoft.com/customer/license/trialLicense/?product=dwtddv
Dynamsoft.DDV.Core.license = "DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9";
Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/engine";
await Dynamsoft.DDV.Core.init();
3.2 Create the Edit Viewer
// Create a Dynamsoft Document Viewer Edit Viewer to display and edit documents scanned with Dynamic Web TWAIN
let editViewer;
editViewer = new Dynamsoft.DDV.EditViewer({
container: "container",
});
// Create a Dynamsoft Document Viewer document to contain and display images scanned by Dynamic Web TWAIN
let ddvDoc;
ddvDoc = Dynamsoft.DDV.documentManager.createDocument({
name: "ddvtestDoc"
});
// Open the document
editViewer.openDocument(ddvDoc.uid);
Links to related documentation:
API Reference
- Dynamsoft Document Viewer:
3.3 Create a Viewerless Dynamic Web TWAIN Instance
Reference a CDN like jsDelivr to fetch most resources using Dynamsoft.DWT.ResourcesPath. Notably these resources exclude DWT Service installers, which exceed the jsDelivr CDN per-file size limit. You have a few options to set this path with Dynamsoft.DWT.ServiceInstallerLocation:
- Install the DWT SDK, extract the DWT service installers (under path like
C:\Program Files (x86)\Dynamsoft\Dynamic Web TWAIN SDK 19.2\Resources\dist), then self-host the DWT Service installers withDynamsoft.DWT.ServiceInstallerLocation = "https://example.com/DWT/Resources/dist". - Use a different CDN with a higher per-file size limit by referencing the location with
Dynamsoft.DWT.ServiceInstallerLocation = "https://unpkg.com/dwt@19.2.0/dist/dist".
// Create Dynamic Web TWAIN object
// Public trial license which is valid for 24 hours
// You can request a 30-day trial key from https://www.dynamsoft.com/customer/license/trialLicense/?product=dwtddv
Dynamsoft.DWT.ProductKey = "DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9";
Dynamsoft.DWT.UseDefaultViewer = false;
Dynamsoft.DWT.ResourcesPath = "https://cdn.jsdelivr.net/npm/dwt@19.2.0/dist";
// Do not forget to set your installer path
Dynamsoft.DWT.ServiceInstallerLocation = "YOUR_INSTALLER_PATH_HERE";
let DWObject;
// Create a Dynamic Web TWAIN instance without the built-in viewer
Dynamsoft.DWT.CreateDWTObjectEx({
WebTwainId: "dwtId",
},function (object) {
DWObject = object;
}, function (error) {
console.log(error);
}
);
API Reference
- Dynamic Web TWAIN:
4. Use SDK Features
4.1 Add Simple Scanning Functionality
Use the Dynamic Web TWAIN instance for scanning. Upon scan completion, import the scanned data into DDV for viewing, editing, and annotating.
4.1.1 Register the OnPostTransferAsync Event
//Register the OnPostTransferAsync event in the success callback function of CreateDWTObjectEx.
Dynamsoft.DWT.CreateDWTObjectEx({
WebTwainId: "dwtId",
},
function (object) {
DWObject = object;
// Call Dynamsoft_OnPostTransferAsync upon completion of every individual page scan
DWObject.RegisterEvent("OnPostTransferAsync", Dynamsoft_OnPostTransferAsync);
},
function (error) {
console.log(error);
}
);
// Import scanned page into Dynamsoft Document Viewer to display
function Dynamsoft_OnPostTransferAsync(outputInfo){
if(DWObject) {
let index = DWObject.ImageIDToIndex(outputInfo.imageId);
DWObject.ConvertToBlob(
[index],
Dynamsoft.DWT.EnumDWT_ImageType.IT_PNG,
function(blob){
ddvDoc.loadSource(blob);
},
function(ec,es){
console.log(es);
}
);
}
}
API Reference
- Dynamic Web TWAIN:
- Dynamsoft Document Viewer:
4.1.2 Use Dynamic Web TWAIN to Scan from Document Scanners
function AcquireImage() {
if (DWObject) {
DWObject.SelectSourceAsync().then(function () {
return DWObject.AcquireImageAsync({
IfCloseSourceAfterAcquire: true
});
}).catch(function (exp) {
alert(exp.message);
});
}
}
API Reference
- Dynamic Web TWAIN:
4.2 Add PDF Saving to Local Functionality
Use saveToPdf() from DDV to convert the scanned document to a PDF Blob, then use saveBlob from DWT to export the document to local as a PDF.
const pdfSettings = {
saveAnnotation: "annotation"
};
function SavePDF(){
editViewer.currentDocument.saveToPdf(pdfSettings).then(function(blob){
DWObject.IfShowFileDialog = true;
DWObject.saveBlob("WebTWAINImage.pdf", blob).then(function () {
console.log("OK");
}).catch(function (err) {
console.log(err);
});
});
}
API Reference
- Dynamic Web TWAIN:
- Dynamsoft Document Viewer:
4.3 Add Server Upload Functionality
Use the saveToPdf() API from DDV to convert the scanned document to a PDF Blob, then use the httpUploadBlob() API from DWT to upload the document to the server as a PDF.
// Can be discarded if already defined previously
const pdfSettings = {
saveAnnotation: "annotation"
};
function Upload(){
editViewer.currentDocument.saveToPdf(pdfSettings).then(function(blob){
let fileName = "WebTWAINImage.pdf";
DWObject.httpUploadBlob(
"https://demo.dynamsoft.com/sample-uploads/",
blob,
fileName
).then(function () {
console.log("Upload successful.");
}).catch(function (err) {
console.log(err);
});
});
}
Links to related documentation:
API Reference
- Dynamic Web TWAIN:
- Dynamsoft Document Viewer:
Review the Complete Code
<!DOCTYPE html>
<html>
<head>
<title>HelloWorld</title>
<script src=" https://cdn.jsdelivr.net/npm/dwt@19.2.0/dist/dynamsoft.webtwain.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/ddv.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/ddv.css">
</head>
<body>
<button onclick="AcquireImage();">Scan</button>
<button onclick="SavePDF();">Save PDF</button>
<button onclick="Upload();">Upload</button>
<div id="container" style="height:580px; width: 1000px;"></div>
</body>
<script type="text/javascript">
let DWObject, editViewer, ddvDoc;
(async function(){
// Dynamsoft Document Viewer
// Public trial license which is valid for 24 hours
// You can request a 30-day trial key from https://www.dynamsoft.com/customer/license/trialLicense/?product=dwtddv
let license = "DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9";
Dynamsoft.DDV.Core.license = license;
Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@3.0.0/dist/engine";
await Dynamsoft.DDV.Core.init();
// Create a Dynamsoft Document Viewer Edit Viewer to display and edit documents scanned with Dynamic Web TWAIN
editViewer = new Dynamsoft.DDV.EditViewer({
container: "container"
});
// Create a Dynamsoft Document Viewer document to contain and display images scanned by Dynamic Web TWAIN
ddvDoc = Dynamsoft.DDV.documentManager.createDocument({
name: "ddvtestDoc"
});
// Open the document
editViewer.openDocument(ddvDoc.uid);
// Create Dynamic Web TWAIN object
Dynamsoft.DWT.ProductKey = license;
Dynamsoft.DWT.UseDefaultViewer = false;
Dynamsoft.DWT.ResourcesPath = "https://cdn.jsdelivr.net/npm/dwt@19.2.0/dist";
// Do not forget to set your installer path
Dynamsoft.DWT.ServiceInstallerLocation = "YOUR_INSTALLER_PATH_HERE";
// Create a Dynamic Web TWAIN instance without the built-in viewer
Dynamsoft.DWT.CreateDWTObjectEx({
WebTwainId: "dwtId",
},function (object) {
DWObject = object;
// Call Dynamsoft_OnPostTransferAsync upon completion of every individual page scan
DWObject.RegisterEvent("OnPostTransferAsync", Dynamsoft_OnPostTransferAsync);
}, function (error) {
console.log(error);
});
})();
// Import scanned page into Dynamsoft Document Viewer to display
function Dynamsoft_OnPostTransferAsync(outputInfo){
if(DWObject) {
let index = DWObject.ImageIDToIndex(outputInfo.imageId);
DWObject.ConvertToBlob(
[index],
Dynamsoft.DWT.EnumDWT_ImageType.IT_PNG,
function(blob){
ddvDoc.loadSource(blob);
},
function(ec,es){
console.log(es);
}
);
}
}
// Scan with Dynamic Web TWAIN
function AcquireImage() {
if (DWObject) {
DWObject.SelectSourceAsync().then(function () {
return DWObject.AcquireImageAsync({
IfCloseSourceAfterAcquire: true
});
}).catch(function (exp) {
alert(exp.message);
});
}
}
const pdfSettings = {
saveAnnotation: "annotation"
};
function SavePDF(){
editViewer.currentDocument.saveToPdf(pdfSettings).then(function(blob){
DWObject.IfShowFileDialog = true;
DWObject.saveBlob("WebTWAINImage.pdf", blob).then(function () {
console.log("OK");
}).catch(function (err) {
console.log(err);
});
});
}
function Upload(){
editViewer.currentDocument.saveToPdf(pdfSettings).then(function(blob){
let fileName = "WebTWAINImage.pdf";
DWObject.httpUploadBlob(
"https://demo.dynamsoft.com/sample-uploads/",
blob,
fileName
).then(function () {
console.log("Upload successful.");
}).catch(function (err) {
console.log(err);
});
});
}
</script>
</html>
Run the Web Application

Further Reading
Use the API to edit images within the controlUse the API to delete or switch images within the control
Original post creation date: Sep 03, 2024
Last modified date: Sep 20, 2024