跳到主要内容

从旧版迁移到 1.0

随着我们转向 Cornerstone3D 库,我们引入了一套新的 API, 它与旧的 Cornerstone 库并不向后兼容。本页为已经在用旧版 Cornerstone 的用户提供一份迁移指南。

Important

请注意这份内容仍在完善中,我们还在继续补全这些迁移指南。

init​

旧版 Cornerstone 不需要初始化,但旧版 CornerstoneTools 需要初始化。 在 Cornerstone3D 中,core 和 tools 两者在使用前都需要初始化。

cornerstoneTools.init();

enabledElement​

Cornerstone3D 中的「已启用元素」不像 Cornerstone 那样孤立存在。 设置布局时,元素是作为输出目标与某个渲染引擎绑定在一起的; 绑定发生时,它们才被视为「已启用」。

Cornerstone3D 为此提供了两个 API:

  • setViewports:一次性启用一组视口
  • enableElement:一次启用一个视口
const element = document.getElementById('div-element');
cornerstone.enable(element);

// 触发 ELEMENT_ENABLED 事件

loadAndCacheImage​

在旧版 Cornerstone 中,你会用 loadAndCacheImage API 加载并缓存影像。 但在 Cornerstone3D 中,应当用视口的 API 来加载和缓存影像。

cornerstone.loadAndCacheImage(imageId).then((image) => {
// 做事情,例如显示一张影像
});

displayImage​

这里的差别在于:你现在是按视口设置数据,而不像 Cornerstone 那样按元素设置。 视口稍后被渲染时,会把视口实例返回给你, 其上带有访问 HTML 元素、渲染器等等的辅助方法。

cornerstone.displayImage(image, element);

// 触发 cornerstone.events.IMAGE_RENDERED
// 其 eventDetail 如下
const eventDetail = {
viewport: enabledElement.viewport,
element,
image,
enabledElement,
canvasContext: enabledElement.canvas.getContext('2d'),
renderTimeInMs,
};

updateImage​

目前的思路基本相同,只是我们提供了三个不同的辅助方法可用于触发渲染:

  • 某个渲染引擎下的所有视口。
  • 单个视口。

当使用那些可能同时影响多个、且都需要更新的视口的工具时 (例如在三个正交 MPR 视图上同时跳到某个十字定位线位置), 这些便捷辅助方法就很有用。

cornerstone.updateImage(element, invalidated);

disable​

视口何时被启用 / 禁用由渲染引擎控制,它会在需要时触发相应的事件。

cornerstone.disable(element);
// 触发 ELEMENT_DISABLED 事件

pageToPixel 与 pixelToCanvas​

我们不再一次只渲染一张影像。在 Cornerstone3D 中, 视口渲染的是三维空间中某个特定的平面,由相机参数 (焦点、视锥体、裁剪范围等)决定。数据和标注都存储在三维空间中 (「世界空间」,按参考坐标系划分),因此要在屏幕上与标注交互、 并渲染出它们的呈现形式,你就必须能在画布空间与世界空间之间做换算。

需要说明的是,为了让堆栈视口与体数据视口能共用工具, 我们也在三维空间中渲染堆栈视口。所以本质上, 它们就是依据自身元数据在空间中定好位置和方位的二维影像。

// 坐标映射函数
cornerstone.pageToPixel(element, pageX, pageY);
cornerstone.pixelToCanvas(element, { x, y });

getPixels​

getPixels 那套做法在三维下不再成立,因为你可能正在以任意(斜切)平面查看数据。 此外,该视口里可能正在渲染包含多份体数据的融合结果(例如 PET/CT)。 开发者现在需要自己取得数据数组,再按各自的具体场景使用这些数据。

cornerstone.getPixels(element, x, y, width, height);

事件​

下表展示了事件数据结构的一些预期变化。关键差异在于:

  • 若干 ID 会作为核心 API 方法的查找键(renderingEngineId、viewportId、volumeId)。 这类似于目前自定义事件中提供的 enabledElement 属性, 可用来取得正在被可视化的全部影像数据。
  • 交互发生时的状态快照,会以该视口参考坐标系下的世界坐标返回相机属性和坐标。
CornerstoneToolsCornerstoneTools3D结构变化的原因
无renderingEngineId驱动该视口的渲染引擎实例的 Id。
无viewportId该视口自身的 Id。
viewport: {
scale,
translation: { x, y },
voi: { windowWidth, windowCenter, windowWidth, windowCenter},
invert,
pixelReplication,
rotation,
hflip,
vflip,
modalityLUT,
voiLUT,
colormap,
labelmap,
displayedArea: {
tlhc: { x, y },
brhc: { x, y },
rowPixelSpacing,
columnPixelSpacing,
presentationSizeMode: 'NONE'
}
}
camera: {
(viewUp,
viewPlaneNormal,
position,
focalPoint,
orthogonalOrPerspective,
viewAngle);
}
以前 viewport 描述的是二维状态,而要唯一确定三维视图我们需要更多信息。 水平和垂直翻转不再是对视图的改动,而是施加在场景中体数据 actor 本身上的一个变换。
// 影像内的二维位置

startPoints / lastPoints / currentPoints / deltaPoints: {
Page,
Image,
Client,
}
// 世界空间中的三维位置
{
(CanvasCoord, WorldCoord);
}
画布坐标定义了该事件发生在二维画布上的什么位置。我们同时还给出在「由焦点和相机法向所确定的那个平面」上投影得到的世界坐标(三维)。