NexScanner Web SDK 使用说明

Copyright (c) 2026 侠医软件. All rights reserved.

NexScanner Web SDK 封装了插件的 WebSocket 协议。业务系统只需要调用 SDK 方法,不需要自己处理原生 WebSocket、二进制图片帧、Base64 分块拼接和命令响应匹配。

文件位置

文件说明
examples/sdk/nexscanner-sdk.js浏览器端 SDK
examples/sdk/nexscanner-sdk.d.tsTypeScript 类型声明
examples/sdk/nexscanner-sdk-demo.html完整 Demo
docs/NexScanner-Web-SDK使用说明.html本说明文档

快速开始

先启动 NexScanner 插件,并确认 WebSocket 服务已启用。默认地址:

ws://127.0.0.1:11345/

在页面中引入 SDK:

<script src="./nexscanner-sdk.js"></script>

最小示例:

<img id="preview">
<script>
const scanner = new NexScannerClient({ url: 'ws://127.0.0.1:11345/' });

scanner.on('image', image => {
  document.querySelector('#preview').src = image.url;
  console.log('收到扫描图片', image.seq, image.blob);
});

async function startScan() {
  await scanner.connect();
  const devices = await scanner.listScanners();
  await scanner.connectScanner(devices[0]);
  await scanner.setParams({
    resolution: 300,
    colormode: 2,
    duplex: 0,
    source: 1,
    format: 'jpg',
    backend: 'WIA',
    brightness: 0,
    contrast: 0
  });
  await scanner.scan();
}
</script>

创建客户端

const scanner = new NexScannerClient({
  url: 'ws://127.0.0.1:11345/',
  timeout: 15000,
  autoReconnect: false,
  reconnectDelay: 3000
});

连接与设备

await scanner.connect();
const devices = await scanner.listScanners();
await scanner.connectScanner(devices[0]);
await scanner.disconnectScanner();
scanner.disconnect();

扫描参数

await scanner.setParams({
  resolution: 300,
  colormode: 2,   // 0 黑白,1 灰度,2 彩色
  duplex: 0,      // 0 单面,1 双面
  source: 1,      // 0 自动,1 平板,2 ADF
  format: 'jpg',
  backend: 'WIA', // WIA / TWAIN / SCAN
  brightness: 0,  // 亮度,部分扫描仪不支持
  contrast: 0     // 对比度,部分扫描仪不支持
});

const params = await scanner.getParams();
const status = await scanner.getStatus();

开始和停止扫描

await scanner.scan();
await scanner.stopScan();

扫描图片由插件主动推送,结果通过 image 事件返回,不是 scan() 的返回值。

scanner.on('image', image => {
  console.log(image.seq);
  console.log(image.format);
  console.log(image.bytes); // ArrayBuffer
  console.log(image.blob);  // Blob
  console.log(image.url);   // 可直接给 img.src 使用
});

图片编辑

扫描图片编辑需要传入插件返回的图片序号 seq,会调用插件的 edit_image 接口。坐标和宽高均为相对比例,范围 0~1。

旋转

await scanner.rotateLeft(seq);
await scanner.rotateRight(seq);
await scanner.rotate180(seq);
await scanner.rotate(seq, 90);

裁剪

// 从图片 10%,10% 的位置开始,裁剪 80% 宽、80% 高
await scanner.crop(seq, 0.1, 0.1, 0.8, 0.8);

矩形标注、颜色、线条宽度

// 在图片上画红色矩形,线宽 3px
await scanner.annotateRect(seq, 0.1, 0.1, 0.5, 0.3, '#ff0000', 3);

// 蓝色粗线
await scanner.annotateRect(seq, 0.2, 0.2, 0.4, 0.2, '#0066ff', 8);

编辑后的图片通过 edit 事件返回:

scanner.on('edit', image => {
  document.querySelector('#preview').src = image.url;
});

Demo 中的裁剪和标注采用拖框模式:点击“裁剪”或“矩形标注”后,直接在大图预览区域拖动选择范围;Demo 会自动把拖框位置换算成 0~1 的相对坐标并调用 SDK。

选择本地图片

SDK 也提供本地图片选择能力。选择本地图片不需要连接插件,本地图片的旋转、裁剪、标注都在浏览器中完成,不调用插件接口。

const images = await scanner.pickLocalImages({
  multiple: true,
  accept: 'image/*'
});

const image = images[0];
document.querySelector('#preview').src = image.url;

本地图片编辑

本地图片没有插件返回的 seq,所以使用本地编辑方法;编辑结果会直接返回新的图片对象。Demo 中本地图片同样支持拖框裁剪和拖框标注。

const rotated = await scanner.rotateLocalImage(image, 90);
const cropped = await scanner.cropLocalImage(image, 0.1, 0.1, 0.8, 0.8);
const marked = await scanner.annotateLocalImage(image, 0.1, 0.1, 0.5, 0.3, '#ff0000', 3);

document.querySelector('#preview').src = marked.url;

事件列表

事件说明
openWebSocket 已连接
closeWebSocket 已断开
errorWebSocket 错误
send已发送命令
command收到命令响应
image收到扫描图片
edit收到编辑后的图片
image-meta收到图片元数据
edit-meta收到编辑元数据
text收到非 JSON 文本

自定义命令

如果后续插件新增命令,可以直接调用 command,不需要修改 SDK:

const resp = await scanner.command('get_status');

运行 Demo

直接打开:

examples/sdk/nexscanner-sdk-demo.html

或放到任意静态 Web 服务中访问。

注意事项