利用HTML5和JavaScript构建一个完整的DICOM Viewer涉及到许多的重要功能。LEADTOOLS医疗图像开发包提供了建立零足迹DICOM Viewer所需的全部功能:图像显示、图像处理、客户端医学影像“调窗”、Series Stack和注释等。接下来,咱们将深刻介绍HTML5 DICOM Viewer、PACS查询/检索以及医学影像“调窗”等功能。java
LEADTOOLS HTML5 DICOM Viewer功能介绍:canvas
DICOM图像HTML5注释数组
一旦选中DICOM系列,图像开始连接到查看器,而且注解实现初始化。完成AnnAutomationManager对象的建立并链接到查看器。服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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);
}
|
使用注释前,你须要选择所须要绘制的对象,或者使用Select工具修改现有注释。app
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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服务加载和保存注释工具
加载和保存注释功能对医疗应用程序的工做流程是很是重要的。首先,它们用于说明和指出图像中注意的事项。固然,最重要的仍然是图像自己,因此最好可以隐藏和显示注释。spa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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);
}
|
当图像帧被加载完后,应用程序会进行快速的权限检查,而后检索与图像关联的先前保存的注释文件数组。code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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();
}
}
|
若是图像有注释,则加载按钮被启用。单击“加载”按钮会弹出一个与图像关联的注释对话框。用户选择一个注释文件后,下列代码能够从服务器获取注释数据,而后将注释添加至canvas。对象
下图为iPhone设备上的图像和注释效果:blog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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"
);
}
}
|