scanonweb 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -140
- package/dist/index.d.ts +180 -0
- package/dist/scanonweb.cjs.js +294 -468
- package/dist/scanonweb.esm.js +294 -468
- package/dist/scanonweb.umd.js +294 -468
- package/dist/scanonweb.umd.min.js +4 -4
- package/package.json +4 -3
- package/src/index.d.ts +114 -200
- package/src/index.js +375 -422
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* scanonweb
|
|
3
|
-
* ScanOnWeb - 扫描控件 JavaScript SDK
|
|
2
|
+
* scanonweb v2.0.0
|
|
3
|
+
* ScanOnWeb - 扫描控件 JavaScript SDK,支持 v2 协议、scanSource 和增量图像事件
|
|
4
4
|
* https://www.brainysoft.cn
|
|
5
5
|
*
|
|
6
|
-
* Copyright (c)
|
|
6
|
+
* Copyright (c) 2026 BrainySoft
|
|
7
7
|
* Licensed under the MIT license
|
|
8
8
|
*/
|
|
9
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).ScanOnWeb=t()}(this,(function(){"use strict";class e{constructor(){this.scaner_work_config={showUI:!1,dpi_x:300,dpi_y:300,deviceIndex:0,showDialog:!1,autoFeedEnable:!0,autoFeed:!1,dupxMode:!1,autoDeskew:!1,autoBorderDetection:!1,colorMode:"RGB",transMode:"memory"},this.h5socket=null,this.imageCount=0,this.tryConnect()}getConnectedServer(e){return console.log("尝试连接托盘扫描服务websocket服务器..."),new Promise(((t,o)=>{const a=new WebSocket(e[0]);a.onopen=()=>{t(a)},a.onerror=e=>{o(e)}})).then((e=>(console.log("连接websocket服务器成功!"),this.initWebsocketCallback(e),console.log("尝试获取扫描设备列表..."),this.loadDevices(),e)),(t=>{if(e.length>1)return this.getConnectedServer(e.slice(1));throw t}))}tryConnect(){this.getConnectedServer(["ws://127.0.0.1:1001","ws://127.0.0.1:2001","ws://127.0.0.1:3001","ws://127.0.0.1:4001","ws://127.0.0.1:5001"])}initWebsocketCallback(e){this.h5socket=e,this.h5socket.onerror=this.onSocketError.bind(this),this.h5socket.onmessage=this.onSocketMessage.bind(this)}onSocketError(e){alert("无法连接扫描服务程序,请检查扫描服务程序是否已经启动!"),console.log("WebSocket error: "+e.data)}isCallbackExist(e){return!(!e||void 0===e||void 0===e)&&"function"==typeof e}onSocketMessage(e){const t=JSON.parse(e.data);switch(t.cmd_type){case"getDevicesList":this.isCallbackExist(this.onGetDevicesListEvent)&&this.onGetDevicesListEvent(t);break;case"scanComplete":this.imageCount=t.imageCount,this.isCallbackExist(this.onScanFinishedEvent)&&this.onScanFinishedEvent(t);break;case"selectScanDevice":this.scaner_work_config.deviceIndex=t.currentIndex,this.scaner_work_config.showDialog=t.showDialog,this.scaner_work_config.autoFeedEnable=t.autoFeedEnable,this.scaner_work_config.autoFeed=t.autoFeed,this.scaner_work_config.dupxMode=t.dupxMode,this.scaner_work_config.autoDeskew=t.autoDeskew,this.scaner_work_config.autoBorderDetection=t.autoBorderDetection,this.isCallbackExist(this.onSelectScanDeviceEvent)&&this.onSelectScanDeviceEvent(t);break;case"getImageCount":this.imageCount=t.imageCount,this.isCallbackExist(this.onGetImageCountEvent)&&this.onGetImageCountEvent(t);break;case"getAllImage":this.imageCount=t.imageCount,this.isCallbackExist(this.onGetAllImageEvent)&&this.onGetAllImageEvent(t);break;case"getImageById":this.imageCount=t.imageCount,this.isCallbackExist(this.onGetImageByIdEvent)&&this.onGetImageByIdEvent(t);break;case"loadImageFromUrl":this.imageCount=t.imageCount,this.isCallbackExist(this.onLoadImageFromUrlEvent)&&this.onLoadImageFromUrlEvent(t);break;case"loadImageFromBase64":this.imageCount=t.imageCount,this.isCallbackExist(this.onLoadImageFromBase64Event)&&this.onLoadImageFromBase64Event(t);break;case"rotateImage":this.imageCount=t.imageCount,this.isCallbackExist(this.onRotateImageEvent)&&this.onRotateImageEvent(t);break;case"getImageSize":this.imageCount=t.imageCount,this.isCallbackExist(this.onGetImageSizeEvent)&&this.onGetImageSizeEvent(t);break;case"uploadAllImageAsPdfToUrl":this.isCallbackExist(this.onUploadAllImageAsPdfToUrlEvent)&&this.onUploadAllImageAsPdfToUrlEvent(t);break;case"uploadAllImageAsTiffToUrl":this.isCallbackExist(this.onUploadAllImageAsTiffToUrlEvent)&&this.onUploadAllImageAsTiffToUrlEvent(t);break;case"uploadJpgImageByIndex":this.isCallbackExist(this.onUploadJpgImageByIndexEvent)&&this.onUploadJpgImageByIndexEvent(t);break;case"upload":this.imageCount=t.imageCount,this.isCallbackExist(this.onUploadEvent)&&this.onUploadEvent(t);break;case"imageEdited":this.isCallbackExist(this.onImageEditedEvent)&&this.onImageEditedEvent(t);break;case"imageDrap":this.isCallbackExist(this.onImageDrapEvent)&&this.onImageDrapEvent(t)}}sendWebSocketCommand(e){try{1===this.h5socket.readyState?this.h5socket.send(JSON.stringify(e)):alert("发送扫描指令失败!请刷新页面或者检查托盘扫描程序是否已经正常运行!")}catch(e){alert("发送扫描指令失败!"+e)}}setLicenseKey(e,t,o,a){const s={cmd_type:"setLicenseKey",licenseMode:e,key1:t,key2:o,url:a};this.sendWebSocketCommand(s)}loadDevices(){this.sendWebSocketCommand({cmd_type:"getDevicesList"})}selectScanDevice(e){const t={cmd_type:"selectScanDevice",deviceIndex:e};this.sendWebSocketCommand(t)}startScan(){const e={cmd_type:"startScan",config:this.scaner_work_config};this.sendWebSocketCommand(e)}clearAll(){this.sendWebSocketCommand({cmd_type:"clearAll"})}getImageCount(){this.sendWebSocketCommand({cmd_type:"getImageCount"})}getAllImage(){this.sendWebSocketCommand({cmd_type:"getAllImage"})}getImageById(e){const t={cmd_type:"getImageById",index:e};this.sendWebSocketCommand(t)}loadImageFromUrl(e,t){if(!t){const o=e.split(".").pop().toLowerCase();t="pdf"===o?"pdf":"tiff"===o||"tif"===o?"tiff":(["jpg","jpeg","png","bmp","gif","webp"].includes(o),"image")}const o={cmd_type:"loadImageFromUrl",url:e,type:t};this.sendWebSocketCommand(o)}loadImageFromBase64(e,t="jpg"){if(e.startsWith("data:")){const o=e.indexOf("base64,");if(-1!==o){const a=e.match(/data:image\/(\w+);/);a&&a[1]&&!t&&(t="jpeg"===a[1]?"jpg":a[1]),e=e.substring(o+7)}}const o={cmd_type:"loadImageFromBase64",base64Data:e,format:t};this.sendWebSocketCommand(o)}rotateImage(e,t){const o={cmd_type:"rotateImage",index:e,angle:t};this.sendWebSocketCommand(o)}getImageSize(e){const t={cmd_type:"getImageSize",index:e};this.sendWebSocketCommand(t)}deleteImageByIndex(e){const t={cmd_type:"deleteImageByIndex",index:e};this.sendWebSocketCommand(t)}uploadAllImageAsPdfToUrl(e,t,o){const a={cmd_type:"uploadAllImageAsPdfToUrl",url:e,id:t,desc:o};this.sendWebSocketCommand(a)}uploadAllImageAsTiffToUrl(e,t,o){const a={cmd_type:"uploadAllImageAsTiffToUrl",url:e,id:t,desc:o};this.sendWebSocketCommand(a)}uploadJpgImageByIndex(e,t,o,a){const s={cmd_type:"uploadJpgImageByIndex",index:a,url:e,id:t,desc:o};this.sendWebSocketCommand(s)}saveAllImageToLocal(e){const t={cmd_type:"saveAllImageToLocal",filename:e};this.sendWebSocketCommand(t)}openClientLocalfile(){this.sendWebSocketCommand({cmd_type:"openClientLocalfile"})}ftpUploadAllImage(e,t,o,a,s,n){const i={cmd_type:"ftpUploadAllImage",serverIp:e,port:t,username:o,password:a,serverPath:s,filename:n};this.sendWebSocketCommand(i)}setUploadButtonVisible(e){const t={cmd_type:"setUploadButtonVisible",visible:e};this.sendWebSocketCommand(t)}setFocus(){this.sendWebSocketCommand({cmd_type:"focus"})}hidden(){this.sendWebSocketCommand({cmd_type:"hidden"})}closeWebSocket(){this.h5socket.close()}loadMultipleImagesFromBase64(e){Array.isArray(e)&&0!==e.length?e.forEach(((e,t)=>{setTimeout((()=>{this.loadImageFromBase64(e.data,e.format||"jpg")}),100*t)})):console.error("loadMultipleImagesFromBase64: 参数必须是非空数组")}loadImageFromCanvas(e,t="jpg",o=.9){if(!(e&&e instanceof HTMLCanvasElement))return void console.error("loadImageFromCanvas: 参数必须是有效的Canvas元素");const a="jpg"===t?"image/jpeg":`image/${t}`,s=e.toDataURL(a,o).split(",")[1];this.loadImageFromBase64(s,t)}loadImageFromFileInput(e){if(!e||!e.files||0===e.files.length)return void console.error("loadImageFromFileInput: 没有选择文件");Array.from(e.files).forEach(((e,t)=>{if(!e.type.startsWith("image/"))return void console.warn(`跳过非图像文件: ${e.name}`);const o=new FileReader;o.onload=o=>{const a=o.target.result,s=e.name.split(".").pop().toLowerCase(),n="jpeg"===s?"jpg":s;setTimeout((()=>{this.loadImageFromBase64(a,n)}),100*t)},o.readAsDataURL(e)}))}}return"undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.ScanOnWeb=e),e}));
|
|
9
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).ScanOnWeb=o()}(this,(function(){"use strict";class e{constructor(){this.protocolVersion=2,this.serverProtocolVersion=null,this.imageCount=0,this.scaner_work_config={showUI:!1,dpi_x:300,dpi_y:300,deviceIndex:0,showDialog:!1,scanSource:"flatbed",autoFeed:!1,dupxMode:!1,autoDeskew:!1,autoBorderDetection:!1,colorMode:"RGB",transMode:"memory"},this.h5socket=null,this.tryConnect()}getConnectedServer(e){return console.log("尝试连接托盘扫描服务websocket服务器..."),new Promise(((o,t)=>{const a=new WebSocket(e[0]);a.onopen=()=>{o(a)},a.onerror=e=>{t(e)}})).then((e=>(console.log("连接websocket服务器成功!"),this.initWebsocketCallback(e),console.log("尝试获取扫描设备列表..."),this.loadDevices(),e)),(o=>{if(e.length>1)return this.getConnectedServer(e.slice(1));throw o}))}tryConnect(){this.getConnectedServer(["ws://127.0.0.1:1001","ws://127.0.0.1:2001","ws://127.0.0.1:3001","ws://127.0.0.1:4001","ws://127.0.0.1:5001"])}initWebsocketCallback(e){this.h5socket=e,this.h5socket.onerror=this.onSocketError.bind(this),this.h5socket.onmessage=this.onSocketMessage.bind(this)}onSocketError(e){alert("无法连接扫描服务程序,请检查扫描服务程序是否已经启动!"),console.log("WebSocket error: "+e.data)}isCallbackExist(e){return!(!e||void 0===e||void 0===e)&&"function"==typeof e}dispatchCallback(e,o){this.isCallbackExist(this[e])&&this[e](o)}toBoolCompat(e){if("boolean"==typeof e)return e;if("number"==typeof e)return 0!==e;if("string"==typeof e){const o=e.trim().toLowerCase();return["1","true","yes","y","on","adf"].includes(o)}return!!e}toIntCompat(e,o){const t=Number(e);return Number.isInteger(t)?t:o}normalizeScanSource(e,o){if("string"==typeof e){const o=e.trim().toLowerCase();if("adf"===o||"feeder"===o||"documentfeeder"===o||"document_feeder"===o||"automatic_document_feeder"===o)return"adf";if("flatbed"===o||"flat_bed"===o||"platen"===o)return"flatbed"}return this.toBoolCompat(o)?"adf":"flatbed"}getLegacyAutoFeedEnable(e){return"adf"===this.normalizeScanSource(e)}shouldIncludeLegacyAutoFeedEnable(){return null===this.serverProtocolVersion||this.serverProtocolVersion<2}normalizeScanConfig(e,o){const t=Object.assign({},this.scaner_work_config,e||{}),a=!o||!1!==o.includeLegacyAutoFeedEnable,s={showUI:this.toBoolCompat(t.showUI),dpi_x:this.toIntCompat(t.dpi_x,300),dpi_y:this.toIntCompat(t.dpi_y,300),deviceIndex:this.toIntCompat(t.deviceIndex,0),showDialog:this.toBoolCompat(t.showDialog),scanSource:this.normalizeScanSource(t.scanSource,t.autoFeedEnable),autoFeed:this.toBoolCompat(t.autoFeed),dupxMode:this.toBoolCompat(t.dupxMode),autoDeskew:this.toBoolCompat(t.autoDeskew),autoBorderDetection:this.toBoolCompat(t.autoBorderDetection),colorMode:t.colorMode||"RGB",transMode:t.transMode||"memory"};return a&&(s.autoFeedEnable=this.getLegacyAutoFeedEnable(s.scanSource)),s}recordServerProtocolVersion(e){const o=this.toIntCompat(e&&e.protocolVersion,1);return this.serverProtocolVersion=o,o}applyIncomingScanConfig(e){this.scaner_work_config.deviceIndex=this.toIntCompat(e.currentIndex,this.scaner_work_config.deviceIndex),Object.prototype.hasOwnProperty.call(e,"showDialog")&&(this.scaner_work_config.showDialog=this.toBoolCompat(e.showDialog)),this.scaner_work_config.scanSource=this.normalizeScanSource(e.scanSource,e.autoFeedEnable),Object.prototype.hasOwnProperty.call(e,"autoFeed")&&(this.scaner_work_config.autoFeed=this.toBoolCompat(e.autoFeed)),Object.prototype.hasOwnProperty.call(e,"dupxMode")&&(this.scaner_work_config.dupxMode=this.toBoolCompat(e.dupxMode)),Object.prototype.hasOwnProperty.call(e,"autoDeskew")&&(this.scaner_work_config.autoDeskew=this.toBoolCompat(e.autoDeskew)),Object.prototype.hasOwnProperty.call(e,"autoBorderDetection")&&(this.scaner_work_config.autoBorderDetection=this.toBoolCompat(e.autoBorderDetection)),"string"==typeof e.colorMode&&e.colorMode&&(this.scaner_work_config.colorMode=e.colorMode),"string"==typeof e.transMode&&e.transMode&&(this.scaner_work_config.transMode=e.transMode),this.scaner_work_config.autoFeedEnable=this.getLegacyAutoFeedEnable(this.scaner_work_config.scanSource)}normalizeIncomingMessage(e){const o=Object.assign({},e||{}),t=this.recordServerProtocolVersion(o),a="string"==typeof o.cmd_type?o.cmd_type:"";switch(o.scanSource||(o.scanSource=this.normalizeScanSource(o.scanSource,o.autoFeedEnable)),a){case"getAllImage":o.cmd_type="imageListSnapshot";break;case"getImageById":o.cmd_type="imageSnapshot";break;case"imageDrap":o.cmd_type="imageMoved"}return o.protocolVersion||(o.protocolVersion=t),o}onSocketMessage(e){const o=JSON.parse(e.data),t=this.normalizeIncomingMessage(o);switch("number"==typeof t.imageCount&&(this.imageCount=t.imageCount),t.cmd_type){case"getDevicesList":this.dispatchCallback("onGetDevicesListEvent",t);break;case"scanComplete":this.dispatchCallback("onScanFinishedEvent",t);break;case"selectScanDevice":this.applyIncomingScanConfig(t),this.dispatchCallback("onSelectScanDeviceEvent",t);break;case"getImageCount":this.dispatchCallback("onGetImageCountEvent",t);break;case"imageListSnapshot":this.dispatchCallback("onImageListSnapshotEvent",t),this.dispatchCallback("onGetAllImageEvent",t);break;case"imageSnapshot":this.dispatchCallback("onImageSnapshotEvent",t),this.dispatchCallback("onGetImageByIdEvent",t);break;case"scanPageAdded":this.dispatchCallback("onScanPageAddedEvent",t);break;case"loadImageFromUrl":this.dispatchCallback("onLoadImageFromUrlEvent",t);break;case"loadImageFromBase64":this.dispatchCallback("onLoadImageFromBase64Event",t);break;case"rotateImage":this.dispatchCallback("onRotateImageEvent",t);break;case"getImageSize":this.dispatchCallback("onGetImageSizeEvent",t);break;case"uploadAllImageAsPdfToUrl":this.dispatchCallback("onUploadAllImageAsPdfToUrlEvent",t);break;case"uploadAllImageAsTiffToUrl":this.dispatchCallback("onUploadAllImageAsTiffToUrlEvent",t);break;case"uploadJpgImageByIndex":this.dispatchCallback("onUploadJpgImageByIndexEvent",t);break;case"upload":this.dispatchCallback("onUploadEvent",t);break;case"imageEdited":this.dispatchCallback("onImageEditedEvent",t);break;case"imageMoved":this.dispatchCallback("onImageMovedEvent",t),this.dispatchCallback("onImageDrapEvent",t);break;case"imageDeleted":this.dispatchCallback("onImageDeletedEvent",t);break;case"imagesCleared":this.dispatchCallback("onImagesClearedEvent",t)}}normalizeOutgoingCommand(e){const o=Object.assign({},e||{});return o.protocolVersion=this.protocolVersion,"startScan"===o.cmd_type&&(o.config=this.normalizeScanConfig(o.config||this.scaner_work_config,{includeLegacyAutoFeedEnable:this.shouldIncludeLegacyAutoFeedEnable()})),o}sendWebSocketCommand(e){try{this.h5socket&&1===this.h5socket.readyState?this.h5socket.send(JSON.stringify(this.normalizeOutgoingCommand(e))):alert("发送扫描指令失败!请刷新页面或者检查托盘扫描程序是否已经正常运行!")}catch(e){alert("发送扫描指令失败!"+e)}}setLicenseKey(e,o,t,a){this.sendWebSocketCommand({cmd_type:"setLicenseKey",licenseMode:e,key1:o,key2:t,url:a})}loadDevices(){this.sendWebSocketCommand({cmd_type:"getDevicesList"})}selectScanDevice(e){this.sendWebSocketCommand({cmd_type:"selectScanDevice",deviceIndex:e})}startScan(){this.sendWebSocketCommand({cmd_type:"startScan",config:this.scaner_work_config})}clearAll(){this.sendWebSocketCommand({cmd_type:"clearAll"})}getImageCount(){this.sendWebSocketCommand({cmd_type:"getImageCount"})}getAllImage(){this.sendWebSocketCommand({cmd_type:"getAllImage"})}getImageById(e){const o={cmd_type:"getImageById"};"string"==typeof e&&e.trim()?o.imageId=e.trim():o.index=e,this.sendWebSocketCommand(o)}loadImageFromUrl(e,o){if(!o){const t=e.split(".").pop().toLowerCase();o="pdf"===t?"pdf":"tiff"===t||"tif"===t?"tiff":(["jpg","jpeg","png","bmp","gif","webp"].includes(t),"image")}this.sendWebSocketCommand({cmd_type:"loadImageFromUrl",url:e,type:o})}loadImageFromBase64(e,o){let t=o||"jpg",a=e;if(a.startsWith("data:")){const e=a.indexOf("base64,");if(-1!==e){if(!o){const e=a.match(/data:image\/(\w+);/);e&&e[1]&&(t="jpeg"===e[1]?"jpg":e[1])}a=a.substring(e+7)}}this.sendWebSocketCommand({cmd_type:"loadImageFromBase64",base64Data:a,format:t})}rotateImage(e,o){this.sendWebSocketCommand({cmd_type:"rotateImage",index:e,angle:o})}getImageSize(e){this.sendWebSocketCommand({cmd_type:"getImageSize",index:e})}deleteImageByIndex(e,o){const t={cmd_type:"deleteImageByIndex",index:e};"string"==typeof o&&o.trim()&&(t.imageId=o.trim()),this.sendWebSocketCommand(t)}moveImage(e,o){this.sendWebSocketCommand({cmd_type:"moveImage",oldIndex:e,newIndex:o})}uploadAllImageAsPdfToUrl(e,o,t){this.sendWebSocketCommand({cmd_type:"uploadAllImageAsPdfToUrl",url:e,id:o,desc:t})}uploadAllImageAsTiffToUrl(e,o,t){this.sendWebSocketCommand({cmd_type:"uploadAllImageAsTiffToUrl",url:e,id:o,desc:t})}uploadJpgImageByIndex(e,o,t,a){this.sendWebSocketCommand({cmd_type:"uploadJpgImageByIndex",index:a,url:e,id:o,desc:t})}saveAllImageToLocal(e){this.sendWebSocketCommand({cmd_type:"saveAllImageToLocal",filename:e})}openClientLocalfile(){this.sendWebSocketCommand({cmd_type:"openClientLocalfile"})}ftpUploadAllImage(e,o,t,a,s,n){this.sendWebSocketCommand({cmd_type:"ftpUploadAllImage",serverIp:e,port:o,username:t,password:a,serverPath:s,filename:n})}setUploadButtonVisible(e){this.sendWebSocketCommand({cmd_type:"setUploadButtonVisible",visible:e})}setFocus(){this.sendWebSocketCommand({cmd_type:"focus"})}hidden(){this.sendWebSocketCommand({cmd_type:"hidden"})}closeWebSocket(){this.h5socket.close()}loadMultipleImagesFromBase64(e){Array.isArray(e)&&0!==e.length?e.forEach(((e,o)=>{setTimeout((()=>{this.loadImageFromBase64(e.data,e.format||"jpg")}),100*o)})):console.error("loadMultipleImagesFromBase64: 参数必须是非空数组")}loadImageFromCanvas(e,o,t){const a=o||"jpg",s="number"==typeof t?t:.9;if(!(e&&e instanceof HTMLCanvasElement))return void console.error("loadImageFromCanvas: 参数必须是有效的Canvas元素");const n="jpg"===a?"image/jpeg":"image/"+a,i=e.toDataURL(n,s).split(",")[1];this.loadImageFromBase64(i,a)}loadImageFromFileInput(e){if(!e||!e.files||0===e.files.length)return void console.error("loadImageFromFileInput: 没有选择文件");Array.from(e.files).forEach(((e,o)=>{if(!e.type.startsWith("image/"))return void console.warn("跳过非图像文件: "+e.name);const t=new FileReader;t.onload=t=>{const a=t.target.result,s=e.name.split(".").pop().toLowerCase(),n="jpeg"===s?"jpg":s;setTimeout((()=>{this.loadImageFromBase64(a,n)}),100*o)},t.readAsDataURL(e)}))}}return"undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof window&&(window.ScanOnWeb=e),e}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scanonweb",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "ScanOnWeb - 扫描控件 JavaScript SDK
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "ScanOnWeb - 扫描控件 JavaScript SDK,支持 v2 协议、scanSource 和增量图像事件",
|
|
5
5
|
"main": "dist/scanonweb.cjs.js",
|
|
6
6
|
"module": "dist/scanonweb.esm.js",
|
|
7
7
|
"browser": "dist/scanonweb.umd.js",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"LICENSE"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "rollup -c",
|
|
16
|
+
"build": "npm run clean && rollup -c && npm run copy:types",
|
|
17
|
+
"copy:types": "node scripts/copy-types.js",
|
|
17
18
|
"dev": "rollup -c -w",
|
|
18
19
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
19
20
|
"prepublishOnly": "npm run build",
|
package/src/index.d.ts
CHANGED
|
@@ -1,73 +1,96 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*/
|
|
1
|
+
export type ScanSource = "flatbed" | "adf";
|
|
2
|
+
export type ColorMode = "RGB" | "BW" | "GRAY";
|
|
3
|
+
export type TransferMode = "memory" | "file" | "native";
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
* 扫描配置参数接口
|
|
8
|
-
*/
|
|
9
5
|
export interface ScanConfig {
|
|
10
|
-
/** 是否显示扫描控件工作界面 */
|
|
11
6
|
showUI: boolean;
|
|
12
|
-
/** DPI 分辨率 X */
|
|
13
7
|
dpi_x: number;
|
|
14
|
-
/** DPI 分辨率 Y */
|
|
15
8
|
dpi_y: number;
|
|
16
|
-
/** 选中的扫描仪硬件设备id索引 */
|
|
17
9
|
deviceIndex: number;
|
|
18
|
-
/** 是否显示设备内置对话框 */
|
|
19
10
|
showDialog: boolean;
|
|
20
|
-
|
|
21
|
-
autoFeedEnable: boolean;
|
|
22
|
-
/** 是否自动装填纸张 */
|
|
11
|
+
scanSource: ScanSource;
|
|
23
12
|
autoFeed: boolean;
|
|
24
|
-
/** 是否使用双面扫描模式 */
|
|
25
13
|
dupxMode: boolean;
|
|
26
|
-
/** 是否使用自动纠偏模式 */
|
|
27
14
|
autoDeskew: boolean;
|
|
28
|
-
/** 是否使用自动边框检测 */
|
|
29
15
|
autoBorderDetection: boolean;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
|
|
16
|
+
colorMode: ColorMode;
|
|
17
|
+
transMode: TransferMode;
|
|
18
|
+
/** Legacy compatibility only. Prefer `scanSource`. */
|
|
19
|
+
autoFeedEnable?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ImageInfo {
|
|
23
|
+
index: number;
|
|
24
|
+
imageId?: string;
|
|
25
|
+
width?: number;
|
|
26
|
+
height?: number;
|
|
27
|
+
imageBase64?: string;
|
|
28
|
+
[key: string]: any;
|
|
34
29
|
}
|
|
35
30
|
|
|
36
|
-
/**
|
|
37
|
-
* WebSocket 消息接口
|
|
38
|
-
*/
|
|
39
31
|
export interface WebSocketMessage {
|
|
40
|
-
/** 命令类型 */
|
|
41
32
|
cmd_type: string;
|
|
42
|
-
|
|
33
|
+
protocolVersion?: number;
|
|
34
|
+
ok?: boolean;
|
|
35
|
+
success?: boolean;
|
|
43
36
|
imageCount?: number;
|
|
44
|
-
/** 当前设备索引 */
|
|
45
37
|
currentIndex?: number;
|
|
46
|
-
|
|
38
|
+
currentSelected?: number;
|
|
39
|
+
selectedImageId?: string | null;
|
|
40
|
+
imageId?: string;
|
|
41
|
+
imageIndex?: number;
|
|
42
|
+
index?: number;
|
|
43
|
+
oldIndex?: number;
|
|
44
|
+
newIndex?: number;
|
|
45
|
+
beforeIndex?: number;
|
|
46
|
+
afterIndex?: number;
|
|
47
|
+
beforeImageCount?: number;
|
|
48
|
+
afterImageCount?: number;
|
|
49
|
+
scanSource?: ScanSource;
|
|
50
|
+
autoFeedEnable?: boolean;
|
|
51
|
+
autoFeed?: boolean;
|
|
52
|
+
dupxMode?: boolean;
|
|
53
|
+
autoDeskew?: boolean;
|
|
54
|
+
autoBorderDetection?: boolean;
|
|
55
|
+
colorMode?: ColorMode | string;
|
|
56
|
+
transMode?: TransferMode | string;
|
|
57
|
+
scanJobId?: string;
|
|
58
|
+
source?: string;
|
|
59
|
+
loadedCount?: number;
|
|
60
|
+
imageAfterCount?: number;
|
|
61
|
+
images?: string[];
|
|
62
|
+
imageInfos?: ImageInfo[];
|
|
63
|
+
imageBase64?: string;
|
|
64
|
+
devices?: any[];
|
|
47
65
|
[key: string]: any;
|
|
48
66
|
}
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
export interface Base64ImagePayload {
|
|
69
|
+
data: string;
|
|
70
|
+
format?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
53
73
|
export default class ScanOnWeb {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
protocolVersion: number;
|
|
75
|
+
serverProtocolVersion: number | null;
|
|
76
|
+
scaner_work_config: ScanConfig & {
|
|
77
|
+
/** Legacy compatibility only. Prefer `scanSource`. */
|
|
78
|
+
autoFeedEnable?: boolean;
|
|
79
|
+
};
|
|
58
80
|
h5socket: WebSocket | null;
|
|
59
|
-
|
|
60
|
-
/** 扫描结果图像总数 */
|
|
61
81
|
imageCount: number;
|
|
62
82
|
|
|
63
|
-
// 事件回调函数(可选)
|
|
64
83
|
onGetDevicesListEvent?: (msg: WebSocketMessage) => void;
|
|
65
84
|
onScanFinishedEvent?: (msg: WebSocketMessage) => void;
|
|
66
85
|
onSelectScanDeviceEvent?: (msg: WebSocketMessage) => void;
|
|
67
86
|
onGetImageCountEvent?: (msg: WebSocketMessage) => void;
|
|
87
|
+
onImageListSnapshotEvent?: (msg: WebSocketMessage) => void;
|
|
88
|
+
onImageSnapshotEvent?: (msg: WebSocketMessage) => void;
|
|
89
|
+
onScanPageAddedEvent?: (msg: WebSocketMessage) => void;
|
|
68
90
|
onGetAllImageEvent?: (msg: WebSocketMessage) => void;
|
|
69
91
|
onGetImageByIdEvent?: (msg: WebSocketMessage) => void;
|
|
70
92
|
onLoadImageFromUrlEvent?: (msg: WebSocketMessage) => void;
|
|
93
|
+
onLoadImageFromBase64Event?: (msg: WebSocketMessage) => void;
|
|
71
94
|
onRotateImageEvent?: (msg: WebSocketMessage) => void;
|
|
72
95
|
onGetImageSizeEvent?: (msg: WebSocketMessage) => void;
|
|
73
96
|
onUploadAllImageAsPdfToUrlEvent?: (msg: WebSocketMessage) => void;
|
|
@@ -75,192 +98,83 @@ export default class ScanOnWeb {
|
|
|
75
98
|
onUploadJpgImageByIndexEvent?: (msg: WebSocketMessage) => void;
|
|
76
99
|
onUploadEvent?: (msg: WebSocketMessage) => void;
|
|
77
100
|
onImageEditedEvent?: (msg: WebSocketMessage) => void;
|
|
101
|
+
onImageMovedEvent?: (msg: WebSocketMessage) => void;
|
|
78
102
|
onImageDrapEvent?: (msg: WebSocketMessage) => void;
|
|
103
|
+
onImageDeletedEvent?: (msg: WebSocketMessage) => void;
|
|
104
|
+
onImagesClearedEvent?: (msg: WebSocketMessage) => void;
|
|
79
105
|
|
|
80
|
-
/**
|
|
81
|
-
* 构造函数
|
|
82
|
-
*/
|
|
83
106
|
constructor();
|
|
84
107
|
|
|
85
|
-
/**
|
|
86
|
-
* 通过连接多个websocket server端口返回一个可用的websocket连接对象
|
|
87
|
-
* @param wssUrls WebSocket服务器URL数组
|
|
88
|
-
* @returns WebSocket连接Promise
|
|
89
|
-
*/
|
|
90
108
|
getConnectedServer(wssUrls: string[]): Promise<WebSocket>;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* 尝试检测websocket哪个端口可以成功连接
|
|
94
|
-
*/
|
|
95
109
|
tryConnect(): void;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 初始化websocket相关的函数绑定
|
|
99
|
-
* @param server WebSocket服务器实例
|
|
100
|
-
*/
|
|
101
110
|
initWebsocketCallback(server: WebSocket): void;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* WebSocket错误处理
|
|
105
|
-
* @param event 错误事件
|
|
106
|
-
*/
|
|
107
111
|
onSocketError(event: Event): void;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 判断回调函数是否存在
|
|
111
|
-
* @param f 要检查的函数
|
|
112
|
-
* @returns 函数是否存在且为函数类型
|
|
113
|
-
*/
|
|
114
112
|
isCallbackExist(f: any): f is Function;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
dispatchCallback(name: string, msg: WebSocketMessage): void;
|
|
114
|
+
toBoolCompat(value: any): boolean;
|
|
115
|
+
toIntCompat(value: any, fallback: number): number;
|
|
116
|
+
normalizeScanSource(
|
|
117
|
+
scanSource?: string | null,
|
|
118
|
+
legacyAutoFeedEnable?: any
|
|
119
|
+
): ScanSource;
|
|
120
|
+
getLegacyAutoFeedEnable(scanSource?: string | null): boolean;
|
|
121
|
+
shouldIncludeLegacyAutoFeedEnable(): boolean;
|
|
122
|
+
normalizeScanConfig(
|
|
123
|
+
config?: Partial<ScanConfig> & { autoFeedEnable?: boolean },
|
|
124
|
+
options?: { includeLegacyAutoFeedEnable?: boolean }
|
|
125
|
+
): ScanConfig & { autoFeedEnable?: boolean };
|
|
126
|
+
recordServerProtocolVersion(msg: WebSocketMessage): number;
|
|
127
|
+
applyIncomingScanConfig(msg: WebSocketMessage): void;
|
|
128
|
+
normalizeIncomingMessage(rawMsg: WebSocketMessage): WebSocketMessage;
|
|
120
129
|
onSocketMessage(event: MessageEvent): void;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 通过websocket发送数据给webscoket服务端
|
|
124
|
-
* @param commandData 要发送的命令数据
|
|
125
|
-
*/
|
|
130
|
+
normalizeOutgoingCommand(commandData: Record<string, any>): Record<string, any>;
|
|
126
131
|
sendWebSocketCommand(commandData: object): void;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
* @param licenseServerUrl 授权服务器URL
|
|
134
|
-
*/
|
|
135
|
-
setLicenseKey(licenseMode: string, key1: string, key2: string, licenseServerUrl: string): void;
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* 加载所有可用的扫描设备
|
|
139
|
-
*/
|
|
132
|
+
setLicenseKey(
|
|
133
|
+
licenseMode: string,
|
|
134
|
+
key1: string,
|
|
135
|
+
key2: string,
|
|
136
|
+
licenseServerUrl: string
|
|
137
|
+
): void;
|
|
140
138
|
loadDevices(): void;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* 设置当前选中的扫描设备id
|
|
144
|
-
* @param deviceIndex 设备索引
|
|
145
|
-
*/
|
|
146
139
|
selectScanDevice(deviceIndex: number): void;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 开始扫描
|
|
150
|
-
*/
|
|
151
140
|
startScan(): void;
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* 清除全部扫描结果
|
|
155
|
-
*/
|
|
156
141
|
clearAll(): void;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 获取图像总数
|
|
160
|
-
*/
|
|
161
142
|
getImageCount(): void;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* 获取所有图像
|
|
165
|
-
*/
|
|
166
143
|
getAllImage(): void;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
* @param index 图像索引
|
|
171
|
-
*/
|
|
172
|
-
getImageById(index: number): void;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* 发送指令远程加载服务器端的多页图像到托盘服务
|
|
176
|
-
* @param url 图像URL
|
|
177
|
-
*/
|
|
178
|
-
loadImageFromUrl(url: string): void;
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* 发送指令旋转某一页图像到托盘服务
|
|
182
|
-
* @param index 图像索引
|
|
183
|
-
* @param angle 旋转角度
|
|
184
|
-
*/
|
|
144
|
+
getImageById(indexOrImageId: number | string): void;
|
|
145
|
+
loadImageFromUrl(url: string, type?: string): void;
|
|
146
|
+
loadImageFromBase64(base64Data: string, format?: string): void;
|
|
185
147
|
rotateImage(index: number, angle: number): void;
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* 发送指令获取某一页图像的宽度到托盘服务
|
|
189
|
-
* @param index 图像索引
|
|
190
|
-
*/
|
|
191
148
|
getImageSize(index: number): void;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
* 发送指令删除某一页图像到托盘服务
|
|
195
|
-
* @param index 图像索引
|
|
196
|
-
*/
|
|
197
|
-
deleteImageByIndex(index: number): void;
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* 以pdf格式上传全部图像到服务器端
|
|
201
|
-
* @param url 上传URL
|
|
202
|
-
* @param id 标识ID
|
|
203
|
-
* @param desc 描述信息
|
|
204
|
-
*/
|
|
149
|
+
deleteImageByIndex(index: number, imageId?: string): void;
|
|
150
|
+
moveImage(oldIndex: number, newIndex: number): void;
|
|
205
151
|
uploadAllImageAsPdfToUrl(url: string, id: string, desc: string): void;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* 以tiff格式上传全部图像到服务器端
|
|
209
|
-
* @param url 上传URL
|
|
210
|
-
* @param id 标识ID
|
|
211
|
-
* @param desc 描述信息
|
|
212
|
-
*/
|
|
213
152
|
uploadAllImageAsTiffToUrl(url: string, id: string, desc: string): void;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
* @param index 图像索引
|
|
221
|
-
*/
|
|
222
|
-
uploadJpgImageByIndex(url: string, id: string, desc: string, index: number): void;
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* 全部图像保存到客户端本地文件
|
|
226
|
-
* @param filename 文件名
|
|
227
|
-
*/
|
|
153
|
+
uploadJpgImageByIndex(
|
|
154
|
+
url: string,
|
|
155
|
+
id: string,
|
|
156
|
+
desc: string,
|
|
157
|
+
index: number
|
|
158
|
+
): void;
|
|
228
159
|
saveAllImageToLocal(filename: string): void;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* 从客户端本地读取图像,通过打开文件对话框选择图像文件
|
|
232
|
-
*/
|
|
233
160
|
openClientLocalfile(): void;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
* @param filename 文件名
|
|
243
|
-
*/
|
|
244
|
-
ftpUploadAllImage(serverIp: string, port: number, username: string, password: string, serverPath: string, filename: string): void;
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* 设置上传按钮是否可见
|
|
248
|
-
* @param visible 是否可见
|
|
249
|
-
*/
|
|
161
|
+
ftpUploadAllImage(
|
|
162
|
+
serverIp: string,
|
|
163
|
+
port: number,
|
|
164
|
+
username: string,
|
|
165
|
+
password: string,
|
|
166
|
+
serverPath: string,
|
|
167
|
+
filename: string
|
|
168
|
+
): void;
|
|
250
169
|
setUploadButtonVisible(visible: boolean): void;
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* 设置焦点
|
|
254
|
-
*/
|
|
255
170
|
setFocus(): void;
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* 隐藏窗口
|
|
259
|
-
*/
|
|
260
171
|
hidden(): void;
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* 关闭websocket连接
|
|
264
|
-
*/
|
|
265
172
|
closeWebSocket(): void;
|
|
173
|
+
loadMultipleImagesFromBase64(base64Images: Base64ImagePayload[]): void;
|
|
174
|
+
loadImageFromCanvas(
|
|
175
|
+
canvas: HTMLCanvasElement,
|
|
176
|
+
format?: string,
|
|
177
|
+
quality?: number
|
|
178
|
+
): void;
|
|
179
|
+
loadImageFromFileInput(fileInput: HTMLInputElement): void;
|
|
266
180
|
}
|