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 CHANGED
@@ -1,16 +1,14 @@
1
1
  # ScanOnWeb
2
2
 
3
- ScanOnWeb 是一个用于与本地扫描服务程序通信的 JavaScript SDK。它通过 WebSocket 连接与本地扫描托盘程序进行通信,提供完整的扫描功能。
3
+ `scanonweb` 是一个通过 WebSocket 与本地 ScanOnWeb 托盘程序通信的 JavaScript SDK
4
4
 
5
- ## 特性
5
+ `2.0.0` 新协议:
6
6
 
7
- - 🔌 WebSocket 通信,支持多端口自动连接
8
- - 📄 支持多种扫描模式(彩色、黑白、灰度)
9
- - 🖼️ 支持图像处理(旋转、编辑、删除)
10
- - 📤 支持多种上传格式(PDF、TIFF、JPG)
11
- - 🔧 支持双面扫描、自动进纸等高级功能
12
- - 📱 支持多种模块格式(UMD、ESM、CJS)
13
- - 🎯 TypeScript 支持
7
+ - 所有命令默认发送 `protocolVersion: 2`
8
+ - 扫描来源改为 `scanSource: "flatbed" | "adf"`
9
+ - 支持增量图像事件:`scanPageAdded`、`imageEdited`、`imageMoved`、`imageDeleted`、`imagesCleared`
10
+ - 支持全量快照事件:`imageListSnapshot`、`imageSnapshot`
11
+ - 仍兼容旧服务端消息和旧回调名
14
12
 
15
13
  ## 安装
16
14
 
@@ -18,190 +16,171 @@ ScanOnWeb 是一个用于与本地扫描服务程序通信的 JavaScript SDK。
18
16
  npm install scanonweb
19
17
  ```
20
18
 
21
- ## 使用方法
19
+ ## 快速开始
22
20
 
23
- ### ES6 模块
21
+ ### ES Module
24
22
 
25
- ```javascript
26
- import ScanOnWeb from 'scanonweb';
23
+ ```js
24
+ import ScanOnWeb from "scanonweb";
27
25
 
28
26
  const scanner = new ScanOnWeb();
29
27
 
30
- // 设置事件回调
28
+ scanner.scaner_work_config.scanSource = "adf";
29
+ scanner.scaner_work_config.autoFeed = true;
30
+ scanner.scaner_work_config.dupxMode = true;
31
+
31
32
  scanner.onGetDevicesListEvent = (msg) => {
32
- console.log('扫描设备列表:', msg);
33
+ console.log("devices:", msg.devices);
34
+ };
35
+
36
+ scanner.onScanPageAddedEvent = (msg) => {
37
+ console.log("page added:", msg.imageId, msg.index);
33
38
  };
34
39
 
35
40
  scanner.onScanFinishedEvent = (msg) => {
36
- console.log('扫描完成:', msg);
41
+ console.log("scan finished:", msg.loadedCount, msg.imageAfterCount);
37
42
  };
38
43
 
39
- // 开始扫描
40
44
  scanner.startScan();
41
45
  ```
42
46
 
43
47
  ### CommonJS
44
48
 
45
- ```javascript
46
- const ScanOnWeb = require('scanonweb');
49
+ ```js
50
+ const ScanOnWeb = require("scanonweb");
47
51
 
48
52
  const scanner = new ScanOnWeb();
49
- // ... 使用方法同上
53
+ scanner.startScan();
50
54
  ```
51
55
 
52
- ### 浏览器 UMD
56
+ ### Browser UMD
53
57
 
54
58
  ```html
55
59
  <script src="node_modules/scanonweb/dist/scanonweb.umd.min.js"></script>
56
60
  <script>
57
61
  const scanner = new ScanOnWeb();
58
-
59
- scanner.onScanFinishedEvent = function(msg) {
60
- console.log('扫描完成:', msg);
61
- };
62
-
63
- scanner.startScan();
62
+ scanner.onImageListSnapshotEvent = (msg) => console.log(msg.imageInfos);
64
63
  </script>
65
64
  ```
66
65
 
67
- ### Vue 3 使用示例
68
-
69
- ```vue
70
- <template>
71
- <div>
72
- <button @click="startScan">开始扫描</button>
73
- <button @click="getDevices">获取设备列表</button>
74
- </div>
75
- </template>
76
-
77
- <script setup>
78
- import { onMounted, ref } from 'vue';
79
- import ScanOnWeb from 'scanonweb';
80
-
81
- const scanner = ref(null);
82
-
83
- onMounted(() => {
84
- scanner.value = new ScanOnWeb();
85
-
86
- // 设置回调函数
87
- scanner.value.onGetDevicesListEvent = (msg) => {
88
- console.log('设备列表:', msg);
89
- };
90
-
91
- scanner.value.onScanFinishedEvent = (msg) => {
92
- console.log('扫描完成:', msg);
93
- };
94
- });
95
-
96
- const startScan = () => {
97
- scanner.value?.startScan();
98
- };
66
+ ## 扫描配置
67
+
68
+ 通过 `scanner.scaner_work_config` 修改默认扫描参数:
99
69
 
100
- const getDevices = () => {
101
- scanner.value?.loadDevices();
70
+ ```js
71
+ scanner.scaner_work_config = {
72
+ showUI: false,
73
+ dpi_x: 300,
74
+ dpi_y: 300,
75
+ deviceIndex: 0,
76
+ showDialog: false,
77
+ scanSource: "flatbed",
78
+ autoFeed: false,
79
+ dupxMode: false,
80
+ autoDeskew: false,
81
+ autoBorderDetection: false,
82
+ colorMode: "RGB",
83
+ transMode: "memory",
102
84
  };
103
- </script>
104
85
  ```
105
86
 
106
- ## API 文档
87
+ ### 关于 2.0 版本中的`scanSource`属性
107
88
 
108
- ### 构造函数
89
+ - `scanSource: "flatbed"` 表示平板
90
+ - `scanSource: "adf"` 表示自动进纸器
91
+ - `autoFeedEnable` 只作为兼容旧版本服务端的遗留字段保留,不建议继续作为主配置使用,建议在代码中移除对autoFeedEnable属性的使用
109
92
 
110
- ```javascript
111
- const scanner = new ScanOnWeb();
112
- ```
93
+ ## 推荐事件模型
113
94
 
114
- ### 配置参数
95
+ 建议按“增量事件 + 可选全量刷新”接入:
115
96
 
116
- 扫描配置参数可以通过 `scanner.scaner_work_config` 访问和修改:
117
-
118
- ```javascript
119
- scanner.scaner_work_config = {
120
- showUI: false, // 是否显示扫描控件工作界面
121
- dpi_x: 300, // DPI 分辨率 X
122
- dpi_y: 300, // DPI 分辨率 Y
123
- deviceIndex: 0, // 选中的扫描仪设备索引
124
- showDialog: false, // 是否显示设备内置对话框
125
- autoFeedEnable: true, // 是否使用自动进纸器
126
- autoFeed: false, // 是否自动装填纸张
127
- dupxMode: false, // 是否使用双面扫描模式
128
- autoDeskew: false, // 是否使用自动纠偏模式
129
- autoBorderDetection: false, // 是否使用自动边框检测
130
- colorMode: 'RGB', // 色彩模式: 'RGB', 'BW', 'GRAY'
131
- transMode: 'memory' // 数据传输模式: 'memory', 'file', 'native'
132
- };
133
- ```
97
+ - `onScanPageAddedEvent`
98
+ - 扫描过程中每新增一页就推送一页
99
+ - `onImageEditedEvent`
100
+ - 托盘端编辑某一页后推送更新
101
+ - `onImageMovedEvent`
102
+ - 托盘端或前端调整顺序后推送顺序变化
103
+ - `onImageDeletedEvent`
104
+ - 删除单页
105
+ - `onImagesClearedEvent`
106
+ - 清空全部结果
107
+ - `onImageListSnapshotEvent`
108
+ - 主动调用 `getAllImage()` 后返回完整快照
109
+ - `onImageSnapshotEvent`
110
+ - 主动调用 `getImageById(indexOrImageId)` 后返回单页快照
134
111
 
135
- ### 主要方法
112
+ ## 兼容性说明
136
113
 
137
- #### 设备管理
138
- - `loadDevices()` - 加载所有可用的扫描设备
139
- - `selectScanDevice(deviceIndex)` - 选择扫描设备
114
+ - SDK 会把旧服务端返回的 `getAllImage` 自动归一化为 `imageListSnapshot`
115
+ - SDK 会把旧服务端返回的 `getImageById` 自动归一化为 `imageSnapshot`
116
+ - SDK 会把旧服务端返回的 `imageDrap` 自动归一化为 `imageMoved`
117
+ - 旧回调仍然会继续触发:
118
+ - `onGetAllImageEvent`
119
+ - `onGetImageByIdEvent`
120
+ - `onImageDrapEvent`
140
121
 
141
- #### 扫描操作
142
- - `startScan()` - 开始扫描
143
- - `clearAll()` - 清除全部扫描结果
122
+ ## 常用 API
144
123
 
145
- #### 图像操作
146
- - `getImageCount()` - 获取图像总数
147
- - `getAllImage()` - 获取所有图像
148
- - `getImageById(index)` - 获取指定索引的图像
149
- - `rotateImage(index, angle)` - 旋转图像
150
- - `deleteImageByIndex(index)` - 删除指定图像
124
+ ### 设备
151
125
 
152
- #### 上传功能
153
- - `uploadAllImageAsPdfToUrl(url, id, desc)` - 以PDF格式上传所有图像
154
- - `uploadAllImageAsTiffToUrl(url, id, desc)` - 以TIFF格式上传所有图像
155
- - `uploadJpgImageByIndex(url, id, desc, index)` - 以JPG格式上传指定图像
126
+ - `loadDevices()`
127
+ - `selectScanDevice(deviceIndex)`
156
128
 
157
- ### 事件回调
129
+ ### 扫描
158
130
 
159
- 设置事件回调函数来处理扫描过程中的各种事件:
131
+ - `startScan()`
132
+ - `clearAll()`
160
133
 
161
- ```javascript
162
- // 获取设备列表回调
163
- scanner.onGetDevicesListEvent = (msg) => {
164
- console.log('设备列表:', msg);
165
- };
134
+ ### 图像
166
135
 
167
- // 扫描完成回调
168
- scanner.onScanFinishedEvent = (msg) => {
169
- console.log('扫描完成,图像数量:', msg.imageCount);
170
- };
136
+ - `getImageCount()`
137
+ - `getAllImage()`
138
+ - `getImageById(indexOrImageId)`
139
+ - `rotateImage(index, angle)`
140
+ - `deleteImageByIndex(index, imageId?)`
141
+ - `moveImage(oldIndex, newIndex)`
171
142
 
172
- // 选择设备回调
173
- scanner.onSelectScanDeviceEvent = (msg) => {
174
- console.log('设备选择完成:', msg);
175
- };
143
+ ### 上传
176
144
 
177
- // 获取图像回调
178
- scanner.onGetImageByIdEvent = (msg) => {
179
- console.log('获取图像:', msg);
180
- };
181
- ```
145
+ - `uploadAllImageAsPdfToUrl(url, id, desc)`
146
+ - `uploadAllImageAsTiffToUrl(url, id, desc)`
147
+ - `uploadJpgImageByIndex(url, id, desc, index)`
182
148
 
183
- ## 系统要求
149
+ ### 扩展加载能力
184
150
 
185
- - 需要安装对应的扫描托盘服务程序
186
- - 支持的浏览器:Chrome、Firefox、Safari、Edge
187
- - Node.js >= 14.0.0(用于服务端)
151
+ - `loadImageFromUrl(url, type?)`
152
+ - `loadImageFromBase64(base64Data, format?)`
153
+ - `loadMultipleImagesFromBase64(base64Images)`
154
+ - `loadImageFromCanvas(canvas, format?, quality?)`
155
+ - `loadImageFromFileInput(fileInput)`
188
156
 
189
- ## 许可证
157
+ ## 更新日志
190
158
 
191
- MIT License
159
+ ### 2.0.0
192
160
 
193
- ## 技术支持
161
+ - 升级为 v2 协议
162
+ - 新增 `protocolVersion` 和 `serverProtocolVersion`
163
+ - 用 `scanSource` 取代歧义更大的 `autoFeedEnable` 作为主配置
164
+ - 新增快照/增量图像事件回调
165
+ - `getImageById` 支持传 `imageId`
166
+ - `deleteImageByIndex` 支持同时传 `imageId`
167
+ - 修复发布包缺少 `dist/index.d.ts`
194
168
 
195
- 如需更多文档帮助请访问官网:https://www.brainysoft.cn
169
+ ### 1.0.3
196
170
 
197
- ## 更新日志
171
+ - 添加 `moveImage`,支持前端调整扫描结果图像顺序
198
172
 
199
173
  ### 1.0.2
200
- - 添加了对加载base64格式图像的支持
201
- - 远程加载图像除了支持pdf和tiff格式,现在也支持加载jpg、png等常见格式的图像
202
-
203
- ### 1.0.1
204
- - 初始版本发布
205
- - 支持基本扫描功能
206
- - 支持多种输出格式
207
- - 添加 TypeScript 支持
174
+
175
+ - 添加加载 Base64 图像支持
176
+ - `loadImageFromUrl` 支持常见图像格式
177
+
178
+ ## 系统要求
179
+
180
+ - 需要本地安装并启动 ScanOnWeb 托盘服务程序
181
+ - 支持现代浏览器
182
+ - Node.js >= 14
183
+
184
+ ## 许可证
185
+
186
+ MIT
@@ -0,0 +1,180 @@
1
+ export type ScanSource = "flatbed" | "adf";
2
+ export type ColorMode = "RGB" | "BW" | "GRAY";
3
+ export type TransferMode = "memory" | "file" | "native";
4
+
5
+ export interface ScanConfig {
6
+ showUI: boolean;
7
+ dpi_x: number;
8
+ dpi_y: number;
9
+ deviceIndex: number;
10
+ showDialog: boolean;
11
+ scanSource: ScanSource;
12
+ autoFeed: boolean;
13
+ dupxMode: boolean;
14
+ autoDeskew: boolean;
15
+ autoBorderDetection: boolean;
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;
29
+ }
30
+
31
+ export interface WebSocketMessage {
32
+ cmd_type: string;
33
+ protocolVersion?: number;
34
+ ok?: boolean;
35
+ success?: boolean;
36
+ imageCount?: number;
37
+ currentIndex?: number;
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[];
65
+ [key: string]: any;
66
+ }
67
+
68
+ export interface Base64ImagePayload {
69
+ data: string;
70
+ format?: string;
71
+ }
72
+
73
+ export default class ScanOnWeb {
74
+ protocolVersion: number;
75
+ serverProtocolVersion: number | null;
76
+ scaner_work_config: ScanConfig & {
77
+ /** Legacy compatibility only. Prefer `scanSource`. */
78
+ autoFeedEnable?: boolean;
79
+ };
80
+ h5socket: WebSocket | null;
81
+ imageCount: number;
82
+
83
+ onGetDevicesListEvent?: (msg: WebSocketMessage) => void;
84
+ onScanFinishedEvent?: (msg: WebSocketMessage) => void;
85
+ onSelectScanDeviceEvent?: (msg: WebSocketMessage) => void;
86
+ onGetImageCountEvent?: (msg: WebSocketMessage) => void;
87
+ onImageListSnapshotEvent?: (msg: WebSocketMessage) => void;
88
+ onImageSnapshotEvent?: (msg: WebSocketMessage) => void;
89
+ onScanPageAddedEvent?: (msg: WebSocketMessage) => void;
90
+ onGetAllImageEvent?: (msg: WebSocketMessage) => void;
91
+ onGetImageByIdEvent?: (msg: WebSocketMessage) => void;
92
+ onLoadImageFromUrlEvent?: (msg: WebSocketMessage) => void;
93
+ onLoadImageFromBase64Event?: (msg: WebSocketMessage) => void;
94
+ onRotateImageEvent?: (msg: WebSocketMessage) => void;
95
+ onGetImageSizeEvent?: (msg: WebSocketMessage) => void;
96
+ onUploadAllImageAsPdfToUrlEvent?: (msg: WebSocketMessage) => void;
97
+ onUploadAllImageAsTiffToUrlEvent?: (msg: WebSocketMessage) => void;
98
+ onUploadJpgImageByIndexEvent?: (msg: WebSocketMessage) => void;
99
+ onUploadEvent?: (msg: WebSocketMessage) => void;
100
+ onImageEditedEvent?: (msg: WebSocketMessage) => void;
101
+ onImageMovedEvent?: (msg: WebSocketMessage) => void;
102
+ onImageDrapEvent?: (msg: WebSocketMessage) => void;
103
+ onImageDeletedEvent?: (msg: WebSocketMessage) => void;
104
+ onImagesClearedEvent?: (msg: WebSocketMessage) => void;
105
+
106
+ constructor();
107
+
108
+ getConnectedServer(wssUrls: string[]): Promise<WebSocket>;
109
+ tryConnect(): void;
110
+ initWebsocketCallback(server: WebSocket): void;
111
+ onSocketError(event: Event): void;
112
+ isCallbackExist(f: any): f is Function;
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;
129
+ onSocketMessage(event: MessageEvent): void;
130
+ normalizeOutgoingCommand(commandData: Record<string, any>): Record<string, any>;
131
+ sendWebSocketCommand(commandData: object): void;
132
+ setLicenseKey(
133
+ licenseMode: string,
134
+ key1: string,
135
+ key2: string,
136
+ licenseServerUrl: string
137
+ ): void;
138
+ loadDevices(): void;
139
+ selectScanDevice(deviceIndex: number): void;
140
+ startScan(): void;
141
+ clearAll(): void;
142
+ getImageCount(): void;
143
+ getAllImage(): void;
144
+ getImageById(indexOrImageId: number | string): void;
145
+ loadImageFromUrl(url: string, type?: string): void;
146
+ loadImageFromBase64(base64Data: string, format?: string): void;
147
+ rotateImage(index: number, angle: number): void;
148
+ getImageSize(index: number): void;
149
+ deleteImageByIndex(index: number, imageId?: string): void;
150
+ moveImage(oldIndex: number, newIndex: number): void;
151
+ uploadAllImageAsPdfToUrl(url: string, id: string, desc: string): void;
152
+ uploadAllImageAsTiffToUrl(url: string, id: string, desc: string): void;
153
+ uploadJpgImageByIndex(
154
+ url: string,
155
+ id: string,
156
+ desc: string,
157
+ index: number
158
+ ): void;
159
+ saveAllImageToLocal(filename: string): void;
160
+ openClientLocalfile(): void;
161
+ ftpUploadAllImage(
162
+ serverIp: string,
163
+ port: number,
164
+ username: string,
165
+ password: string,
166
+ serverPath: string,
167
+ filename: string
168
+ ): void;
169
+ setUploadButtonVisible(visible: boolean): void;
170
+ setFocus(): void;
171
+ hidden(): void;
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;
180
+ }