npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

med-viewer-sdk

v0.1.23

Published

> 面向医学图像分析的高性能查看与标注 SDK,基于 OpenSeadragon 深度缩放引擎,提供插件化架构。

Readme

MedViewer SDK

面向医学图像分析的高性能查看与标注 SDK,基于 OpenSeadragon 深度缩放引擎,提供插件化架构。

特性

  • 深度缩放 — 基于 OpenSeadragon 的高性能瓦片渲染,支持超大病理切片无缝浏览
  • 插件化架构 — 标注、截图、颜色调整、比例尺、放大镜、工具栏等插件按需启用
  • 标注能力 — 集成 Annotorious,支持矩形/多边形/圆形/椭圆/线段/手绘 六种标注工具
  • 颜色调整 — WebGL 加速的亮度/对比度/饱和度/伽马/色相/反色/灰度/怀旧 实时调节
  • 区域截图 — 框选区域并导出为 Blob,支持旋转和像素坐标
  • 工具栏 — 内置深色风格工具栏,支持自定义按钮、下拉面板、激活态
  • Vue 集成 — 提供 Vue 2/3 通用组件 MedViewer,自动管理生命周期
  • 国际化 — 内置中文/英文,支持动态切换

安装

npm install med-viewer-sdk
# 或
pnpm add med-viewer-sdk

Peer Dependencies(需自行安装):

npm install openseadragon vue

快速开始

原生 HTML / UMD

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://unpkg.com/med-viewer-sdk/dist/style.css">
</head>
<body>
  <div id="viewer" style="width:100vw;height:100vh;"></div>

  <script src="https://unpkg.com/openseadragon"></script>
  <script src="https://unpkg.com/med-viewer-sdk"></script>
  <script>
    const engine = new MedViewerSDK.MedViewerEngine({
      osdOptions: {
        id: 'viewer',
        prefixUrl: 'https://openseadragon.github.io/openseadragon/images/',
        tileSources: {
          type: 'image',
          url: './slide.dzi'
        }
      },
      locale: 'zh-CN',
      plugins: {
        toolbar: true,
        annotorious: {
          onCreateAnnotation: (anno) => console.log('新建标注', anno)
        },
        selection: {
          onSelection: (rect, blob) => {
            if (blob) console.log('截图完成', rect, blob)
          }
        },
        colorAdjust: true,
        scalebar: { pixelsPerMeter: 100000 },
        magnification: true
      }
    })
  </script>
</body>
</html>

ES Module

import { MedViewerEngine, ToolbarPosition } from 'med-viewer-sdk'
import 'med-viewer-sdk/dist/style.css'

const engine = new MedViewerEngine({
  osdOptions: {
    id: 'viewer',
    tileSources: 'https://example.com/slide.dzi'
  },
  plugins: {
    toolbar: { position: ToolbarPosition.BOTTOM_CENTER },
    annotorious: true,
    colorAdjust: true
  }
})

Vue 2 / Vue 3

<template>
  <MedViewer :options="viewerOptions" @ready="onReady" />
</template>

<script>
import MedViewer from 'med-viewer-sdk/dist/vue'
import 'med-viewer-sdk/dist/style.css'

export default {
  components: { MedViewer },
  data() {
    return {
      viewerOptions: {
        osdOptions: {
          id: 'my-viewer',
          tileSources: '/slide.dzi'
        },
        locale: 'zh-CN',
        plugins: {
          toolbar: true,
          annotorious: true,
          colorAdjust: true,
          selection: true,
          scalebar: { pixelsPerMeter: 100000 },
          magnification: true
        }
      }
    }
  },
  methods: {
    onReady(engine) {
      // engine 即为 MedViewerEngine 实例
      console.log('引擎就绪', engine)
    }
  }
}
</script>

Vue 组件在 onMounted 时创建引擎,onBeforeUnmount 时自动销毁,无需手动管理。


引擎配置

MedEngineOptions

interface MedEngineOptions {
  osdOptions: OpenSeadragon.Options   // 必填,OpenSeadragon 配置
  locale?: 'zh-CN' | 'en-US'          // 国际化语言,默认 'zh-CN'
  plugins?: {
    annotorious?: boolean | AnnotoriousOptions
    toolbar?: boolean | ToolbarOptions
    colorAdjust?: boolean | ColorAdjustOptions
    selection?: boolean | SelectionOptions
    scalebar?: boolean | ScalebarOptions
    magnification?: boolean | MagnificationOptions
  }
}

true 等同于传 {}(使用默认配置)。

Engine 公开属性

创建后可通过 engine.xxx 访问各插件实例:

| 属性 | 类型 | 说明 | |---|---|---| | engine.viewer | OpenSeadragon.Viewer | 底层 OSD 查看器 | | engine.anno | AnnoAnnotator \| null | 标注插件 | | engine.toolbar | MedToolbar \| null | 工具栏插件 | | engine.colorAdjust | ColorAdjustPlugin \| null | 颜色调整插件 | | engine.selection | SelectionPlugin \| null | 截图插件 | | engine.scalebar | ScalebarPlugin \| null | 比例尺插件 | | engine.magnification | MagnificationPlugin \| null | 放大镜插件 |

Engine 事件

engine.addHandler('ready', () => {
  console.log('图像首次加载完成')
})

插件详解

1. 标注插件 (Annotorious)

提供六种标注工具:矩形、多边形、圆形、椭圆、线段、手绘。

配置

interface AnnotoriousOptions {
  onCreateAnnotation?: (annotation: any) => void
  onUpdateAnnotation?: (annotation: any, previous: any) => void
  onDeleteAnnotation?: (annotation: any) => void
  onCancelAnnotation?: (annotation: any) => void
  locale?: string   // 默认跟随引擎 locale
  options?: {
    formatter?: any  // 标注格式化器
  }
}

API

const anno = engine.anno

// 设置工具
anno.setTool('rect', '#ff0000')       // 启用矩形标注,颜色红色
anno.setTool('polygon', '#00ff00')    // 启用多边形标注
anno.setTool(null)                     // 关闭标注模式

// 启用/禁用
anno.setEnabled(true)
anno.setEnabled(false)

// 数据操作
anno.getAnnotations()     // 获取所有标注
anno.setAnnotations([...]) // 加载标注数据
anno.clear()              // 清除所有标注

// 事件监听
anno.on('modeChange', (state) => {
  console.log(state.enabled, state.tool)
})

事件

| 事件名 | 参数 | 说明 | |---|---|---| | modeChange | { enabled: boolean, tool: string \| null } | 标注模式变化 |


2. 截图插件 (Selection)

框选图像区域并导出为 Blob,支持旋转和像素坐标。

配置

interface SelectionOptions {
  showSelectionControl?: boolean       // 是否显示控件按钮,默认 true
  showConfirmDenyButtons?: boolean     // 是否显示确认/取消按钮,默认 true
  returnPixelCoordinates?: boolean     // 返回像素坐标,默认 true
  keyboardShortcut?: string            // 快捷键,默认 'c'
  allowRotation?: boolean              // 允许旋转选区,默认 true
  restrictToImage?: boolean            // 限制在图像内,默认 false
  onSelection?: (rect: Rect, blob: Blob \| null) => void  // 确认选区回调
  onSelectionCanceled?: () => void     // 取消选区回调
}

API

const sel = engine.selection

sel.enable()          // 启用选择模式
sel.disable()         // 禁用选择模式
sel.toggleState()     // 切换选择模式
sel.isEnabled()       // 查询是否启用
sel.getSelection()    // 获取当前选区
sel.clearSelection()  // 清除选区

// 事件监听
sel.on('selectionEnabled', (enabled: boolean) => {
  console.log('选择模式', enabled ? '开启' : '关闭')
})

事件

| 事件名 | 参数 | 说明 | |---|---|---| | selectionEnabled | boolean | 选择模式启用/禁用 | | selectionStateToggled | boolean | 选择模式切换 |


3. 颜色调整插件 (ColorAdjust)

基于 WebGL 着色器的实时图像处理,内置防抖优化。

配置

interface ColorAdjustOptions {
  adjustments?: ColorAdjustments  // 初始调整值
  debounceMs?: number             // 防抖延迟,默认 60
  loadMode?: 'async' | 'sync'    // 加载模式,默认 'async'
  onAdjustmentsChange?: (adj: ColorAdjustments) => void
}

interface ColorAdjustments {
  brightness?: number   // 亮度 0~2,默认 1
  contrast?: number     // 对比度 0~2,默认 1
  saturation?: number   // 饱和度 0~3,默认 1
  gamma?: number        // 伽马 0.1~3,默认 1
  hue?: number          // 色相 0~360,默认 0
  invert?: boolean      // 反色
  sepia?: boolean       // 怀旧
  greyscale?: boolean   // 灰度
}

API

const ca = engine.colorAdjust

ca.setAdjustments({ brightness: 1.5, contrast: 1.2 })
ca.setAdjustments({ greyscale: true })
ca.adjustments   // 获取当前调整值
ca.reset()       // 重置为默认值

4. 比例尺插件 (Scalebar)

在图像上叠加比例尺标注。

配置

interface ScalebarOptions {
  type?: ScalebarType             // NONE=0, MICROSCOPY=1, MAP=2
  pixelsPerMeter?: number         // 每米像素数
  location?: ScalebarLocation     // NONE=0, TOP_LEFT=1, TOP_RIGHT=2, BOTTOM_RIGHT=3, BOTTOM_LEFT=4
  color?: string
  fontColor?: string
  backgroundColor?: string
  fontSize?: string
  barThickness?: number
  minWidth?: string
}

示例

plugins: {
  scalebar: {
    type: ScalebarType.MICROSCOPY,
    pixelsPerMeter: 100000,
    location: ScalebarLocation.BOTTOM_LEFT
  }
}

5. 放大镜插件 (Magnification)

显示当前放大倍率并提供快捷缩放按钮。

配置

interface MagnificationOptions {
  type?: MagnificationType       // 'LD' 或 'OSD',默认 'OSD'
  position?: MagnificationPosition  // 位置,默认 'MIDDLE_LEFT'
  offsetX?: number
  offsetY?: number
  pixelsPerMeter?: number        // LD 模式需要
}

API

const mag = engine.magnification
mag.getMagnification()  // 获取当前倍率
mag.show()              // 显示
mag.hide()              // 隐藏
mag.toggle()            // 切换可见性
mag.refresh()           // 刷新显示

工具栏

内置工具栏

plugins: {
  toolbar: true  // 使用默认工具栏(重置、标注、颜色调整、截图)
}

自定义位置

import { ToolbarPosition } from 'med-viewer-sdk'

plugins: {
  toolbar: {
    position: ToolbarPosition.BOTTOM_CENTER
  }
}

可选位置:TOP_LEFT TOP_CENTER TOP_RIGHT BOTTOM_LEFT BOTTOM_CENTER BOTTOM_RIGHT MIDDLE_LEFT MIDDLE_RIGHT

自定义按钮

通过 buttons 配置完全控制工具栏按钮,ID 匹配内置按钮时会合并默认配置:

plugins: {
  toolbar: {
    position: ToolbarPosition.BOTTOM_RIGHT,
    buttons: [
      {
        id: 'reset',    // 匹配内置 reset 按钮,覆盖默认配置
        icon: myResetIcon,
        label: '回到原点',
        onClick: (engine, hide) => {
          engine.viewer.viewport.goHome()
          hide()
        }
      },
      {
        id: 'anno'      // 匹配内置 anno 按钮,使用默认 dropdownContent
      },
      {
        id: 'colorAdjust' // 匹配内置 colorAdjust 按钮
      },
      {
        id: 'selection'   // 匹配内置 selection 按钮
      },
      // 添加自定义按钮
      {
        id: 'myTool',
        icon: myToolIcon,
        label: '我的工具',
        onClick: (engine, hide) => {
          console.log('自定义工具被点击')
          hide()
        }
      }
    ]
  }
}

按钮激活态

按钮激活时显示与 hover 相同的高亮效果(绿色背景),支持三种方式:

方式一:命令式 — setButtonActive

最灵活,外部代码随时调用:

// 激活
engine.toolbar.setButtonActive('myTool', true)
// 取消激活
engine.toolbar.setButtonActive('myTool', false)

方式二:声明式 — activeEvent

在按钮配置中声明事件源,Toolbar 自动绑定监听,事件触发时自动更新激活态:

{
  id: 'myTool',
  icon: myToolIcon,
  label: '我的工具',
  onClick: (engine, hide) => { /* ... */ },
  activeEvent: {
    emitter: engine.anno,              // 任何有 .on() 方法的对象
    event: 'modeChange',              // 监听的事件名
    mapToActive: (data) => data.enabled  // 将事件数据映射为 boolean
  }
}

方式三:下拉框联动 — activeOnDropdown

下拉框按钮设为 true,下拉框打开自动激活、关闭自动取消:

{
  id: 'myPanel',
  icon: myPanelIcon,
  label: '我的面板',
  dropdownContent: (engine, hide) => {
    const el = document.createElement('div')
    el.textContent = '面板内容'
    return el
  },
  activeOnDropdown: true
}

内置按钮激活机制

| 按钮 | 激活来源 | 机制 | |---|---|---| | anno | engine.annomodeChange 事件 | 自动监听 | | selection | engine.selectionselectionEnabled 事件 | 自动监听 | | colorAdjust | 下拉框开闭 | activeOnDropdown: true | | reset | 无 | 不激活 |

自定义下拉面板

任何按钮都可以配置 dropdownContent,返回一个 DOM 元素:

{
  id: 'filters',
  icon: filterIcon,
  label: '滤镜',
  activeOnDropdown: true,
  dropdownContent: (engine, hide) => {
    const container = document.createElement('div')
    container.className = 'med-toolbar-dropdown-inner'

    const btn = document.createElement('button')
    btn.className = 'med-tool-item'
    btn.textContent = '模糊'
    btn.onclick = () => {
      // 应用滤镜...
      hide() // 关闭下拉面板
    }

    container.appendChild(btn)
    return container
  }
}

hide() 用于关闭当前下拉面板,务必在操作完成后调用。


Engine 常用 API

图像导航

engine.viewer.viewport.goHome()                    // 回到初始视图
engine.viewer.viewport.zoomTo(2)                   // 缩放到指定级别
engine.viewer.viewport.panTo(new OpenSeadragon.Point(0.5, 0.5))  // 平移到指定位置

跳转到指定位置

// 以指定倍率跳转到图像坐标 (x, y)
await engine.goToPosition({ x: 1000, y: 2000 }, true, 20)
// 参数: target坐标, 是否动画, 目标倍率(mag)
// mag=null 时仅平移,不缩放

AI 标注框

// 加载 AI 检测框
engine.loadAIMarks([
  {
    x: 100, y: 200, width: 50, height: 50,
    style: { border: '2px solid red' },
    labels: [
      { label: '类型', value: '肿瘤', style: { color: '#333', fontSize: 12 } }
    ]
  }
], true)  // true = 显示标签

// 更新
engine.updateAIMarks(newBoxes, showLabel)

// 清除
engine.clearAIMarks()

选区框

engine.loadSelectionBox([
  {
    x: 100, y: 200, width: 50, height: 50,
    style: { border: '2px solid #4CAF50' }
  }
])

语言切换

engine.setLocale('en-US')  // 动态切换为英文
engine.setLocale('zh-CN')  // 切换为中文

销毁

engine.destroy()  // 销毁所有插件和 viewer

国际化

内置中文 (zh-CN) 和英文 (en-US) 两种语言:

| 键 | 中文 | 英文 | |---|---|---| | toolbar.annoColor | 标注颜色 | Annotation Color | | toolbar.annoShape | 标注形状 | Annotation Shape | | toolbar.rect | 矩形 | Rectangle | | toolbar.polygon | 多边形 | Polygon | | toolbar.circle | 圆形 | Circle | | toolbar.ellipse | 椭圆 | Ellipse | | toolbar.line | 线段 | Line | | toolbar.freehand | 手绘 | Freehand | | toolbar.reset | 重置 | Reset | | toolbar.screenshot | 截图 | Screenshot | | toolbar.brightness | 亮度 | Brightness | | toolbar.contrast | 对比度 | Contrast | | toolbar.saturation | 饱和度 | Saturation | | toolbar.gamma | 伽马 | Gamma | | toolbar.hue | 色相 | Hue | | toolbar.invert | 反色 | Invert | | toolbar.sepia | 怀旧 | Sepia | | toolbar.greyscale | 灰度 | Greyscale |


ToolbarButton 接口

interface ToolbarButton {
  id: string                                    // 按钮唯一标识
  label?: string                                // 提示文字
  icon?: string                                 // 图标 URL
  dropdownContent?: (engine, hide) => HTMLElement  // 下拉面板内容
  onClick?: (engine, hide) => void              // 点击回调
  activeEvent?: {                               // 声明式激活状态
    emitter: any                                // 事件发射器(需有 .on())
    event: string                               // 事件名
    mapToActive: (data: any) => boolean         // 事件数据映射
  }
  activeOnDropdown?: boolean                    // 下拉框开闭时自动激活
}

构建与开发

# 安装依赖
npm install

# 构建(生成 dist/ 目录)
npm run build

# 输出格式
# dist/med-viewer-sdk.umd.js   — UMD 格式(<script> 标签引入)
# dist/med-viewer-sdk.mjs      — ESM 格式(import 引入)
# dist/med-viewer-sdk.d.ts     — TypeScript 类型声明
# dist/style.css                — 样式文件

浏览器兼容性

| 浏览器 | 版本 | |---|---| | Chrome | 80+ | | Firefox | 80+ | | Safari | 14+ | | Edge | 80+ |

需要 WebGL 支持以使用颜色调整功能。


依赖说明

| 依赖 | 用途 | |---|---| | openseadragon | 深度缩放图像渲染引擎 | | annotorious-openseadragon-ld | Annotorious 标注库(定制版) | | openseadragon-filtering | OSD 瓦片滤镜处理器 | | svg-path-properties | SVG 路径计算(标注测量) |


License

MIT