在LEADTOOLS构建HTML5 DICOM/PACS查看器(一)一文中,我们介绍了LEADTOOLS的 PACS查询/检索和客户端调窗功能。本文,我们将继续深入了解HTML5 DICOM查看器以及客户端注释和标记。
LEADTOOLS HTML5 DICOM Viewer功能介绍:
- HTML5/JavaScript Viewer Control可创建跨平台的图像查看功能
- 同时支持鼠标和多点触控(手势)输入
- 拥有医学影像“调窗”、Series Stack和图像处理等功能
- 随时随地通过本地存档或DICOM通信连接远程PACS查看DICOM图像
- 原生HTML5图像注释和标记
- 完整的HTML5 DICOM查看器源代码
DICOM图像的HTML5注释
一旦选中了DICOM系列,图像开始流向查看器,接着注释开始被初始化。AnnAutomationManager 对象被创建并绑定与查看器绑定。
function initializeAnnotations() {
_automationManager = new
Leadtools.Annotations.Automation.AnnAutomationManager();
_automationManager.createDefaultObjects();
_automationManager.findObjectById(Leadtools.Annotations.Core.AnnObject.rulerObjectId).get_objectTemplate().set_measurementUnit(6);
_automationManager.findObjectById(Leadtools.Annotations.Core.AnnObject.polyRulerObjectId).get_objectTemplate().set_measurementUnit(6);
_automationManager.findObjectById(Leadtools.Annotations.Core.AnnObject.protractorObjectId).get_objectTemplate().set_measurementUnit(6);
var divElemnt = document.getElementById("ViewerParent");
_overlayCanvas =
document.createElement("canvas");
_overlayCanvas.id = "overlayCanvas";
_overlayCanvas.width = $(divElemnt).width();
_overlayCanvas.height =
$(divElemnt).height();
var parent = document.getElementById(_leadViewer.get_canvasId()).parentNode;
parent.appendChild(_overlayCanvas);
_automationInteractiveMode = new
Leadtools.Annotations.Automation.ImageViewerAutomationControl(_leadViewer);
}
要使用注解,接下来需要做的是选择你所希望绘制的对象,或使用选择工具来修改现成的注释。本演示中包含了几个按钮,点击按钮可以启用所需的注释工具。你可以根据需要启用或禁用某些按钮,但是本示例中自带了医疗行业中最常用的注释(箭头,矩形,椭圆,文本,高亮,尺子,Poly Ruler和量角器)。下列代码片段展示了几个按钮的点击事件:
function OnAnnotationSelect() {
if (null != _leadViewer && null
!= _currentAutomation && _annotationSelect.enabled) {
AutomationService();
_currentAutomation.get_manager().set_currentObjectId(Leadtools.Annotations.Core.AnnObject.selectObjectId);
}
}
function OnAnnotationArrow() {
if (null != _leadViewer
&& null != _currentAutomation && _annotationArrow.enabled) {
AutomationService();
_currentAutomation.get_manager().set_currentObjectId(Leadtools.Annotations.Core.AnnObject.pointerObjectId);
}
}
function OnAnnotationText() {
if (null != _leadViewer && null !=
_currentAutomation && _annotationText.enabled) {
AutomationService();
_currentAutomation.get_manager().set_currentObjectId(Leadtools.Annotations.Core.AnnObject.textObjectId);
}
}
通过Web服务加载和保存注释
加载和保存注释的功能对医疗应用的工作流至关重要。首先,他们可以描述、指出或在图像中标附注。最重要的一点仍然是图像本身,因此注释可以被隐藏或恢复。DICOM查看器也具有协作性。放射科医生,护士,医生和病人都可以看看图片,并通过注释和说明获取第二意见。由于这是一个Web应用程序,因此用户可以通过电脑、平板电脑或移动设备等查看图像和注释。
LEADTOOLS使用RESTful web服务加载和保存注释。如下图所示,第一步是获得一个描述和绘制注释的图像帧。这两部分信息通过JSON发送至userData参数, LEADTOOLS Web服务将注释数据保存至服务器的数据库中。
function DoSaveAnn(annotationsData) {
var firstFrame =
_dicomLoader.GetFrame(0);
var description =
$(‘#annSaveDescText‘).val();
if (!description) {
alert("You must enter a description");
return;
}
var series = firstFrame.Instance.SeriesInstanceUID;
var userData = { Description: description,
ReferencedSOPInstance:
firstFrame.Instance.SOPInstanceUID
};
annotationsProxy.SaveAnnotations(series, annotationsData,
JSON.stringify(userData), SaveAnnotationsError, SaveAnnotationsSuccess);
}
当图像帧被加载时,该应用程序的快速地进行权限检查,然后检索与图像有关的先前保存的注释。
function OnSeriesLoaded(args, frames) {
_overlayManager.SetOverlayTags(frames);
if (_userPermissions.CanViewAnnotations) {
annotationsProxy.FindSeriesAnnotations(frames[0].Instance.SeriesInstanceUID,
FindAnnotationsError, FindAnnotationsSuccess);
}
}
function FindAnnotationsSuccess(annotations) {
if (annotations
&& annotations.length > 0) {
_loadedAnnotationsIds =
annotations;
EnableAnnotationLoad();
}
else {
_loadedAnnotationsIds = null;
DisableAnnotationLoad();
}
}
如果图像带有注释,则加载按钮被启用。点击加载按钮,调出带有与帧相关注释的对话框。用户选择注释文件后,下列代码会从服务器获取注释数据,然后开始将注释添加至画布。
function LoadSelectedServerAnn() {
var annID =
_loadedAnnotationsIds[parseInt($($(".annItemSelected")[0]).attr("annIndex"))];
annotationsProxy.GetAnnotations(annID.AnnotationID, GetAnnotationsError,
GetAnnotationsSuccess);
}
function GetAnnotationsSuccess(annotationsData) {
if (annotationsData)
{
try {
var length = _automationArray.length;
var codecs = new
Leadtools.Annotations.Core.AnnCodecs();
while (length--) {
var frame = _dicomLoader.GetFrame(length);
var
automation = _automationArray[length];
var container =
automation.get_container();
var destChildren =
container.get_children();
var instanceNumber =
frame.Instance.InstanceNumber;
var loadContainer = codecs.loadFromXmlDocument(annotationsData, parseInt (instanceNumber));
if (loadContainer) {
var srcChildren =
loadContainer.get_children();
var childrenCount =
srcChildren.get_count();
for (var i = 0; i < childrenCount; i++) {
var child =
srcChildren.get_item(i);
destChildren.add(child);
}
automation.get_automationControl().automationInvalidate();
}
}
alert("Annotations Loaded");
}
catch (er) {
alert(‘Invalid
annotations data.\n\r‘ + er );
}
}
else {
alert("No
annotations found");
}
}
下面截图显示了从iPhone中加载的相同图像和注释的效果: