This commit is contained in:
mozzie 2023-12-22 16:57:25 +08:00
parent 2761357eac
commit f1824ee928
4 changed files with 167 additions and 20 deletions

View File

@ -33,7 +33,9 @@
"dicomweb-client": "0.10.3",
"@cornerstonejs/tools": "1.41.0",
"@cornerstonejs/streaming-image-volume-loader": "1.41.0",
"@cornerstonejs/calculate-suv": "1.1.0"
"@cornerstonejs/calculate-suv": "1.1.0",
"vtk.js": "29.2.0",
"itk": "14.1.1"
},
"devDependencies": {
"@babel/core": "^7.21.8",

View File

@ -0,0 +1,57 @@
import { useRef, useState } from "react";
import dicomParser from "dicom-parser";
import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';
import vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';
import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import readImageDICOMFileSeries from "itk/readImageDICOMFileSeries";
import vtkITKHelper from '@kitware/vtk.js/Common/DataModel/ITKHelper';
interface LocalMprProps {
children?: JSX.Element;
}
export const LocalMpr = (props: LocalMprProps) => {
const containerRef = useRef(null);
const handleFolderUpload = async (
event: React.ChangeEvent<HTMLInputElement>
) => {
if (event.target.files) {
const files = event.target.files;
const volumeImageData = await readImageDICOMFileSeries(files);
const vtkImage = vtkITKHelper.convertItkToVtkImage(volumeImageData);
const volume = vtkVolume.newInstance();
const mapper = vtkVolumeMapper.newInstance();
mapper.setInputData(vtkImage);
volume.setMapper(mapper);
// 创建 vtk 的全屏渲染窗口
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
background: [0, 0, 0],
container: containerRef.current!,
});
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();
// 将 volume 添加到渲染器
renderer.addVolume(volume);
// 设置相机位置等
renderer.resetCamera();
renderWindow.render();
}
};
return (
<div>
<div>
<input
type="file"
webkitdirectory="true"
directory=""
onChange={handleFolderUpload}
/>
</div>
<div style={{ width: 400, height: 400 }} ref={containerRef}></div>
</div>
);
};

View File

@ -1,5 +1,6 @@
import { CrosshairMpr } from "./Crosshair";
import { DiffViewer } from "./DiffViewer";
import { LocalMpr } from "./LocalMpr";
import { MprViewer } from "./MprViewer";
import { StackViewer } from "./StackViewer";
@ -10,7 +11,8 @@ interface RootViewerProps {
export const RootViewer = (props: RootViewerProps) => {
return (
<div>
<CrosshairMpr />
<LocalMpr />
{/* <CrosshairMpr /> */}
{/* <StackViewer /> */}
</div>
);

View File

@ -56,6 +56,9 @@ importers:
dicomweb-client:
specifier: 0.10.3
version: 0.10.3
itk:
specifier: 14.1.1
version: 14.1.1
js-cookie:
specifier: 3.0.5
version: 3.0.5
@ -92,6 +95,9 @@ importers:
three:
specifier: 0.156.1
version: 0.156.1
vtk.js:
specifier: 29.2.0
version: 29.2.0(@babel/preset-env@7.21.5)(autoprefixer@10.4.15)(webpack@5.75.0)(wslink@1.11.4)
devDependencies:
'@babel/core':
specifier: ^7.21.8
@ -2977,6 +2983,13 @@ packages:
regenerator-runtime: 0.13.11
dev: false
/@babel/runtime@7.22.11:
resolution: {integrity: sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==, tarball: http://192.168.4.201:4873/@babel%2fruntime/-/runtime-7.22.11.tgz}
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.14.0
dev: false
/@babel/runtime@7.22.15:
resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==}
engines: {node: '>=6.9.0'}
@ -4838,6 +4851,10 @@ packages:
resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==}
dev: false
/@types/webxr@0.5.10:
resolution: {integrity: sha512-n3u5sqXQJhf1CS68mw3Wf16FQ4cRPNBBwdYLFzq3UddiADOim1Pn3Y6PBdDilz1vOJF3ybLxJ8ZEDlLIzrOQZg==, tarball: http://192.168.4.201:4873/@types%2fwebxr/-/webxr-0.5.10.tgz}
dev: false
/@types/webxr@0.5.4:
resolution: {integrity: sha512-41gfGLTtqXZhcmoDlLDHqMJDuwAMwhHwXf9Q2job3TUBsvkNfPNI/3IWVEtLH4tyY1ElWtfwIaoNeqeEX238/Q==}
dev: true
@ -5765,6 +5782,11 @@ packages:
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
/at-least-node@1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==, tarball: http://192.168.4.201:4873/at-least-node/-/at-least-node-1.0.0.tgz}
engines: {node: '>= 4.0.0'}
dev: false
/atob@2.1.2:
resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
engines: {node: '>= 4.5.0'}
@ -5802,6 +5824,14 @@ packages:
ee-first: 1.1.1
dev: false
/axios@0.21.4:
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==, tarball: http://192.168.4.201:4873/axios/-/axios-0.21.4.tgz}
dependencies:
follow-redirects: 1.15.2
transitivePeerDependencies:
- debug
dev: false
/axios@1.3.6:
resolution: {integrity: sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==}
dependencies:
@ -6454,7 +6484,7 @@ packages:
engines: {node: '>=14'}
/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, tarball: http://192.168.4.201:4873/commander/-/commander-2.20.3.tgz}
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
@ -7785,7 +7815,7 @@ packages:
dev: true
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, tarball: http://192.168.4.201:4873/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz}
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
@ -8069,14 +8099,24 @@ packages:
dev: true
/fs-extra@8.1.0:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, tarball: http://192.168.4.201:4873/fs-extra/-/fs-extra-8.1.0.tgz}
engines: {node: '>=6 <7 || >=8'}
dependencies:
graceful-fs: 192.168.4.201+4873/graceful-fs@4.2.11
graceful-fs: 4.2.11
jsonfile: 4.0.0
universalify: 0.1.2
dev: true
/fs-extra@9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==, tarball: http://192.168.4.201:4873/fs-extra/-/fs-extra-9.1.0.tgz}
engines: {node: '>=10'}
dependencies:
at-least-node: 1.0.0
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 2.0.0
dev: false
/fs-monkey@1.0.4:
resolution: {integrity: sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==}
@ -8973,6 +9013,21 @@ packages:
resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
engines: {node: '>=6'}
/itk@14.1.1:
resolution: {integrity: sha512-gLHkndNe7s00lYzasdM74IgrxryF5PY5uqlTRXlCXK09l095M8Qs6WKhZm/DEavQ+rhE5tQL1qowqmQTIfUM2A==, tarball: http://192.168.4.201:4873/itk/-/itk-14.1.1.tgz}
hasBin: true
dependencies:
'@babel/runtime': 7.22.15
axios: 0.21.4
commander: 2.20.3
fs-extra: 9.1.0
mime-types: 2.1.35
promise-file-reader: 1.0.3
webworker-promise: 0.4.4
transitivePeerDependencies:
- debug
dev: false
/jest-util@29.6.3:
resolution: {integrity: sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -9106,18 +9161,17 @@ packages:
dev: true
/jsonfile@4.0.0:
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, tarball: http://192.168.4.201:4873/jsonfile/-/jsonfile-4.0.0.tgz}
optionalDependencies:
graceful-fs: 4.2.11
dev: true
/jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, tarball: http://192.168.4.201:4873/jsonfile/-/jsonfile-6.1.0.tgz}
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.11
dev: true
/jsonwebtoken@9.0.0:
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
@ -9549,7 +9603,7 @@ packages:
engines: {node: '>= 0.6'}
/mime-types@2.1.18:
resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==}
resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==, tarball: http://192.168.4.201:4873/mime-types/-/mime-types-2.1.18.tgz}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.33.0
@ -10749,6 +10803,10 @@ packages:
/promise-breaker@6.0.0:
resolution: {integrity: sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==}
/promise-file-reader@1.0.3:
resolution: {integrity: sha512-/sumzg8xjurm6PchjhlXb592lv3tFFaO13DtsFqbglhdZjCzxhDgvmPv/vMcarpfGiCRPC4ZvZ+YsV0am0d4+g==, tarball: http://192.168.4.201:4873/promise-file-reader/-/promise-file-reader-1.0.3.tgz}
dev: false
/proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
@ -11802,7 +11860,7 @@ packages:
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
engines: {node: '>=6'}
dependencies:
graceful-fs: 192.168.4.201+4873/graceful-fs@4.2.11
graceful-fs: 4.2.11
js-yaml: 3.14.1
pify: 4.0.1
strip-bom: 3.0.0
@ -13615,14 +13673,13 @@ packages:
engines: {node: '>=4'}
/universalify@0.1.2:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, tarball: http://192.168.4.201:4873/universalify/-/universalify-0.1.2.tgz}
engines: {node: '>= 4.0.0'}
dev: true
/universalify@2.0.0:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==, tarball: http://192.168.4.201:4873/universalify/-/universalify-2.0.0.tgz}
engines: {node: '>= 10.0.0'}
dev: true
/unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
@ -13800,6 +13857,37 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
/vtk.js@29.2.0(@babel/preset-env@7.21.5)(autoprefixer@10.4.15)(webpack@5.75.0)(wslink@1.11.4):
resolution: {integrity: sha512-z2clkJEYgs78+EAjl+/JTXe4yv98yuZE0g9iTT+xIcT+mKGGOy4Lqq6UNMWv1IWVDqXzprpCK/ucjDox3sJB1w==, tarball: http://192.168.4.201:4873/vtk.js/-/vtk.js-29.2.0.tgz}
hasBin: true
peerDependencies:
'@babel/preset-env': ^7.17.10
autoprefixer: ^10.4.7
wslink: ^1.1.0
dependencies:
'@babel/preset-env': 7.21.5(@babel/core@7.21.8)
'@babel/runtime': 7.22.11
'@types/webxr': 0.5.10
autoprefixer: 10.4.15(postcss@8.4.29)
commander: 9.2.0
d3-scale: 4.0.2
fast-deep-equal: 3.1.3
fflate: 0.7.3
gl-matrix: 3.4.3
globalthis: 1.0.3
seedrandom: 3.0.5
shader-loader: 1.3.1
shelljs: 0.8.5
spark-md5: 3.0.2
stream-browserify: 3.0.0
webworker-promise: 0.5.0
worker-loader: 3.0.8(webpack@5.75.0)
wslink: 1.11.4
xmlbuilder2: 3.0.2
transitivePeerDependencies:
- webpack
dev: false
/watchpack@2.4.0:
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
engines: {node: '>=10.13.0'}
@ -14116,6 +14204,10 @@ packages:
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
engines: {node: '>=0.8.0'}
/webworker-promise@0.4.4:
resolution: {integrity: sha512-NfdSlaWqd+0iSrQudB0N0MELfJ9TVTlynhXMpi06piuZhyc9Yy7Hz6BFu2HUkvIb9lCS0pFW42ptd/JnXVnptg==, tarball: http://192.168.4.201:4873/webworker-promise/-/webworker-promise-0.4.4.tgz}
dev: false
/webworker-promise@0.5.0:
resolution: {integrity: sha512-14iR79jHAV7ozwvbfif+3wCaApT3I1g8Lo0rJZrwAu6wxZGx/08Y8KXz6as6ZLNUEEufeiEBBYrqyDBClXOsEw==, tarball: http://192.168.4.201:4873/webworker-promise/-/webworker-promise-0.5.0.tgz}
dev: false
@ -14785,12 +14877,6 @@ packages:
define-properties: 192.168.4.201+4873/define-properties@1.2.0
dev: false
192.168.4.201+4873/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, registry: http://npm.tavi.fit/, tarball: http://192.168.4.201:4873/graceful-fs/-/graceful-fs-4.2.11.tgz}
name: graceful-fs
version: 4.2.11
dev: true
192.168.4.201+4873/has-property-descriptors@1.0.0:
resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==, registry: http://npm.tavi.fit/, tarball: http://192.168.4.201:4873/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz}
name: has-property-descriptors