Quick start
DQ Scanner lets your web page capture documents from the user's scanner. Add one script, drop in
your license key, and call scan() — each page comes back as an image
(or a single PDF). The user installs the small DQ Scanner service once on their Windows machine.
<script src="http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js"></script>
<script>
const scanner = await DQScanner.create({ licenseKey: "YOUR_KEY" });
const devices = await scanner.getScanners();
const pdf = await scanner.scan({ source: devices[0], format: "pdf" });
// upload `pdf` (a Blob) wherever you like
</script>
1 · Add the SDK
Include the script from your DQ Scanner host:
<script src="http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js"></script>
2 · Your license key
Use the key issued for your domain. Keep it in your page or app config.
const LICENSE_KEY = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...";
3 · Scan
const scanner = await DQScanner.create({ licenseKey: LICENSE_KEY });
const devices = await scanner.getScanners(); // ["Canon MF630", ...]
const pages = await scanner.scan({
source: devices[0],
dpi: 300,
color: "color", // "color" | "gray" | "bw"
quality: 85, // JPEG quality 1-100 for color/gray (b&w stays lossless)
feeder: false, // true = use the document feeder (ADF)
duplex: false, // two-sided (needs feeder)
fastFeeder:false, // ADF via TWAIN continuous feed — fast + reliable duplex on document scanners
skipBlank: false,
onPage: blob => addThumbnail(URL.createObjectURL(blob))
});
console.log(`Scanned ${pages.length} page(s).`); // pages: Blob[]
Scan options
| Field | Type | Notes |
|---|---|---|
source | string | A name from getScanners(). |
dpi | number | e.g. 100 / 150 / 200 / 300 / 600. |
color | string | "color", "gray" or "bw". |
quality | number | 1–100 (default 85). JPEG quality for color/gray; bw is always lossless PNG. Higher = larger file, better for OCR. |
feeder | boolean | Use the automatic document feeder. |
duplex | boolean | Two-sided; requires feeder:true. |
fastFeeder | boolean | Drive the ADF over TWAIN's continuous feed instead of WIA — much faster and reliable duplex on dedicated document scanners (EPSON DS, Fujitsu fi). Leave off for multifunction printers; falls back to WIA automatically if TWAIN fails. Requires feeder:true. |
skipBlank | boolean | Discard blank pages. |
format | string | "images" (default, resolves to Blob[]) or "pdf" (a single PDF Blob). |
onPage | function | Called with each page Blob as it arrives. |
PDF output
Get a single PDF instead of images — either from scan() or from pages you already have.
// scan straight to a PDF Blob
const pdf = await scanner.scan({ source: devices[0], feeder: true, format: "pdf" });
// or build one from pages later
const pdf2 = await DQScanner.convertToPdf(pages, { dpi: 300, quality: 0.85 });
Manage pages (edit before upload)
Collect scanned and imported pages in a buffer, then rotate, replace, reorder or remove them before exporting.
const buffer = DQScanner.createBuffer();
buffer.on("change", b => renderThumbnails(b));
await scanner.scan({ source: devices[0], feeder: true, into: buffer });
// Import existing files (JPG / PNG / PDF) — PDF pages are rasterized for you
const added = await buffer.loadFromFile(); // opens a file picker
await buffer.rotate(0, 90); // rotate the 1st page 90° (90 | 180 | 270)
buffer.replaceAt(1, someBlob); // swap a page
buffer.insertAt(0, someBlob); // insert at a position (default is append)
buffer.move(3, 0); // reorder: move page 4 to the front
buffer.removeAt(2); // delete a page
const pdf = await buffer.toPdf(); // export the final document
buffer.clear();
| Method | Description |
|---|---|
rotate(index, degrees) | Rotate a page in place (90/180/270). Returns a Promise. |
loadFromFile(opts?) | File picker → load JPG/PNG/PDF (PDF pages rasterized). Resolves with the number of pages added. opts: { multiple, accept, scale, at }. |
replaceAt(index, blob) | Replace a page without removing/re-adding. |
insertAt(index, blob) | Insert at a position; returns the index used. |
move(from, to) | Reorder a page. |
removeAt / clear / at / count | Remove, clear, read a page, and the page count. |
PDF import is powered by a bundled renderer served from your portal — your app doesn't need to add pdf.js.
TypeScript / Angular
Types are served next to the SDK: http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.d.ts. Reference it in your project for full IntelliSense on the global DQScanner.
// angular.json -> architect.build.options.scripts
"scripts": [ "http://scanner.daleelteq.cloud/sdk/daleelteq-scanner.js" ]
// component.ts
const scanner = await DQScanner.create({ licenseKey: environment.scannerKey });
const pdf = await scanner.scan({ source: (await scanner.getScanners())[0], format: "pdf" });
If the service isn't installed
getScanners()/scan() wait for the service to appear.
To detect whether it's installed and prompt a download, use ensureRunning():
if (!(await scanner.ensureRunning({ timeout: 12000 }))) {
// Not detected on this machine — send the user to install it.
showInstallDialog();
}
Handling errors
A rejected create() tells you exactly why the key was refused.
try {
const scanner = await DQScanner.create({ licenseKey: LICENSE_KEY });
} catch (e) {
if (e.name === "LicenseError") showBanner(e.message); // expired / wrong domain / invalid
else throw e;
}
Troubleshooting
| Symptom | Fix |
|---|---|
| Never connects | Make sure the DQ Scanner service is installed and running (tray icon). |
LicenseError: not valid for this domain | Use a key issued for this host (or a wildcard). |
| No scanners listed | Confirm the scanner's driver is installed and the device is on. |
| Feeder scan fails | Load paper before scanning. |