Generated
+1
-1
@@ -21838,7 +21838,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/unzipit": {
|
"node_modules/unzipit": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/unzipit/-/unzipit-2.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/unzipit/-/unzipit-2.0.3.tgz",
|
||||||
"integrity": "sha512-e6+ftgSQRj9Hwf2mIWFwYIGqBoKV7AziG/d7pep2Uv3NCzHbhLO5d9dGRwpahVlnpQ7aQC+5kWk72dnWocdYyA==",
|
"integrity": "sha512-e6+ftgSQRj9Hwf2mIWFwYIGqBoKV7AziG/d7pep2Uv3NCzHbhLO5d9dGRwpahVlnpQ7aQC+5kWk72dnWocdYyA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -1057,7 +1057,7 @@ export default {
|
|||||||
|
|
||||||
this.trialId = this.$route.query.trialId
|
this.trialId = this.$route.query.trialId
|
||||||
this.readingTaskState = this.taskInfo.ReadingTaskState
|
this.readingTaskState = this.taskInfo.ReadingTaskState
|
||||||
if (!this.taskInfo.IsBaseLine && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
|
if ((!this.taskInfo.IsBaseLine && this.taskInfo.IsReadingTaskViewInOrder === 1) || this.taskInfo.IsReadingTaskViewInOrder === 2) {
|
||||||
this.rows = 1
|
this.rows = 1
|
||||||
this.cols = 2
|
this.cols = 2
|
||||||
this.activeViewportIndex = 1
|
this.activeViewportIndex = 1
|
||||||
@@ -1425,7 +1425,11 @@ export default {
|
|||||||
|
|
||||||
if (activeStudyIndex > -1 && activeSeriesIndex > -1) {
|
if (activeStudyIndex > -1 && activeSeriesIndex > -1) {
|
||||||
seriesArr.map((i, index) => {
|
seriesArr.map((i, index) => {
|
||||||
this.$refs[`${this.viewportKey}-${index}`][0].setSeriesInfo(i)
|
const allowInitPrefetch = i.TaskInfo.IsCurrentTask === true && index === this.activeViewportIndex
|
||||||
|
this.$refs[`${this.viewportKey}-${index}`][0].setSeriesInfo(i, false, {
|
||||||
|
limitInitPrefetch: allowInitPrefetch,
|
||||||
|
skipInitPrefetch: !allowInitPrefetch
|
||||||
|
})
|
||||||
})
|
})
|
||||||
const visitTaskId = this.visitTaskList[this.activeTaskIndex].VisitTaskId
|
const visitTaskId = this.visitTaskList[this.activeTaskIndex].VisitTaskId
|
||||||
this.lastViewportTaskId = visitTaskId
|
this.lastViewportTaskId = visitTaskId
|
||||||
@@ -1436,7 +1440,7 @@ export default {
|
|||||||
// 初始化加载器
|
// 初始化加载器
|
||||||
async initLoader() {
|
async initLoader() {
|
||||||
await initLibraries()
|
await initLibraries()
|
||||||
cache.setMaxCacheSize(6 * 1024 * 1024 * 1024)
|
cache.setMaxCacheSize(4 * 1024 * 1024 * 1024)
|
||||||
let renderingEngine = getRenderingEngine(renderingEngineId)
|
let renderingEngine = getRenderingEngine(renderingEngineId)
|
||||||
if (!renderingEngine) {
|
if (!renderingEngine) {
|
||||||
renderingEngine = new RenderingEngine(renderingEngineId)
|
renderingEngine = new RenderingEngine(renderingEngineId)
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ import { getPTImageIdInstanceMetadata } from '@/views/trials/trials-panel/readin
|
|||||||
import ptScalingMetaDataProvider from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/ptScalingMetaDataProvider'
|
import ptScalingMetaDataProvider from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/ptScalingMetaDataProvider'
|
||||||
import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv'
|
import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv'
|
||||||
import { vec3 } from 'gl-matrix'
|
import { vec3 } from 'gl-matrix'
|
||||||
|
const InitPrefetchMaxBytes = 2 * 1024 * 1024 * 1024
|
||||||
export default {
|
export default {
|
||||||
name: 'ImageViewport',
|
name: 'ImageViewport',
|
||||||
props: {
|
props: {
|
||||||
@@ -159,7 +160,8 @@ export default {
|
|||||||
wwwcIdx: 2,
|
wwwcIdx: 2,
|
||||||
loading: false,
|
loading: false,
|
||||||
forceFitToWindow: false,
|
forceFitToWindow: false,
|
||||||
resizeObserver: null
|
resizeObserver: null,
|
||||||
|
instanceFileSizeMap: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -210,6 +212,9 @@ export default {
|
|||||||
},
|
},
|
||||||
stackNewImage(e) {
|
stackNewImage(e) {
|
||||||
const { detail } = e
|
const { detail } = e
|
||||||
|
if (this.series?.Modality === 'PT' && detail?.image) {
|
||||||
|
this.cachePTMetadata([detail.image])
|
||||||
|
}
|
||||||
this.series.SliceIndex = detail.imageIdIndex
|
this.series.SliceIndex = detail.imageIdIndex
|
||||||
this.sliderInfo.height = detail.imageIdIndex * 100 / (this.series.Stack.length - 1)
|
this.sliderInfo.height = detail.imageIdIndex * 100 / (this.series.Stack.length - 1)
|
||||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
@@ -475,10 +480,57 @@ export default {
|
|||||||
|
|
||||||
viewport.render()
|
viewport.render()
|
||||||
},
|
},
|
||||||
async prefetchMetadataInformation(imageIdsToPrefetch, modality) {
|
formatBytes(bytes) {
|
||||||
|
const size = Number(bytes)
|
||||||
|
if (!Number.isFinite(size) || size <= 0) return '0 B'
|
||||||
|
if (size >= 1024 * 1024 * 1024) return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`
|
||||||
|
if (size >= 1024 * 1024) return `${(size / 1024 / 1024).toFixed(2)} MB`
|
||||||
|
if (size >= 1024) return `${(size / 1024).toFixed(2)} KB`
|
||||||
|
return `${size} B`
|
||||||
|
},
|
||||||
|
getImageInstanceId(imageId) {
|
||||||
|
try {
|
||||||
|
const rawImageId = imageId.includes(':') ? imageId.slice(imageId.indexOf(':') + 1) : imageId
|
||||||
|
const queryIndex = rawImageId.indexOf('?')
|
||||||
|
if (queryIndex === -1) return ''
|
||||||
|
const searchParams = new URLSearchParams(rawImageId.slice(queryIndex + 1))
|
||||||
|
return searchParams.get('instanceId') || ''
|
||||||
|
} catch (error) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildInstanceFileSizeMap() {
|
||||||
|
console.log('buildInstanceFileSizeMap')
|
||||||
|
const fileSizeMap = {}
|
||||||
|
const instanceList = this.series?.InstanceInfoList || []
|
||||||
|
instanceList.forEach((item) => {
|
||||||
|
const instanceId = item?.Id
|
||||||
|
const fileSize = Number(item.FileSize)
|
||||||
|
if (instanceId !== undefined && instanceId !== null && fileSize > 0) {
|
||||||
|
fileSizeMap[String(instanceId)] = fileSize
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.instanceFileSizeMap = fileSizeMap
|
||||||
|
},
|
||||||
|
getImageFileSizeByImageId(imageId) {
|
||||||
|
const instanceId = this.getImageInstanceId(imageId)
|
||||||
|
if (!instanceId) return 0
|
||||||
|
const fileSize = Number(this.instanceFileSizeMap[String(instanceId)] || 0)
|
||||||
|
return Number.isFinite(fileSize) && fileSize > 0 ? fileSize : 0
|
||||||
|
},
|
||||||
|
async prefetchMetadataInformation(imageIdsToPrefetch, modality, initialLoadedBytes = 0, enableInitPrefetchLimit = false) {
|
||||||
|
let totalLoadedBytes = Number.isFinite(initialLoadedBytes) && initialLoadedBytes > 0 ? initialLoadedBytes : 0
|
||||||
let taskPromises = []
|
let taskPromises = []
|
||||||
for (let i = 0; i < imageIdsToPrefetch.length; i++) {
|
for (let i = 0; i < imageIdsToPrefetch.length; i++) {
|
||||||
|
const imageId = imageIdsToPrefetch[i]
|
||||||
|
const nextImageBytes = this.getImageFileSizeByImageId(imageId)
|
||||||
|
// 初始化预取累计超过 2G 后停止,剩余切片在用户滚动时按需加载
|
||||||
|
if (enableInitPrefetchLimit && (totalLoadedBytes >= InitPrefetchMaxBytes || (nextImageBytes > 0 && totalLoadedBytes + nextImageBytes > InitPrefetchMaxBytes))) {
|
||||||
|
console.info(`[Viewport] 初始化预取累计下载达到 ${this.formatBytes(totalLoadedBytes)},停止继续预取。`)
|
||||||
|
break
|
||||||
|
}
|
||||||
taskPromises.push(cornerstoneDICOMImageLoader.wadouri.loadImage(imageIdsToPrefetch[i]).promise)
|
taskPromises.push(cornerstoneDICOMImageLoader.wadouri.loadImage(imageIdsToPrefetch[i]).promise)
|
||||||
|
totalLoadedBytes += nextImageBytes
|
||||||
if (taskPromises.length >= 6 || i === imageIdsToPrefetch.length - 1) {
|
if (taskPromises.length >= 6 || i === imageIdsToPrefetch.length - 1) {
|
||||||
let res = await Promise.all(taskPromises)
|
let res = await Promise.all(taskPromises)
|
||||||
if (modality === 'PT') {
|
if (modality === 'PT') {
|
||||||
@@ -500,7 +552,7 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async setSeriesInfo(obj, isLocate = false) {
|
async setSeriesInfo(obj, isLocate = false, option = {}) {
|
||||||
try {
|
try {
|
||||||
if (this.series && obj.Id === this.series.Id && obj.Description === this.series.Description && !isLocate) {
|
if (this.series && obj.Id === this.series.Id && obj.Description === this.series.Description && !isLocate) {
|
||||||
obj.SliceIndex = this.series.SliceIndex
|
obj.SliceIndex = this.series.SliceIndex
|
||||||
@@ -510,6 +562,7 @@ export default {
|
|||||||
if (isSameSeries && this.series?.Stack && obj.Stack[obj.SliceIndex] === this.series.Stack[this.series.SliceIndex]) return
|
if (isSameSeries && this.series?.Stack && obj.Stack[obj.SliceIndex] === this.series.Stack[this.series.SliceIndex]) return
|
||||||
this.toggleClipPlay(false)
|
this.toggleClipPlay(false)
|
||||||
this.series = { ...obj }
|
this.series = { ...obj }
|
||||||
|
this.buildInstanceFileSizeMap()
|
||||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
const viewport = renderingEngine.getViewport(this.viewportId)
|
const viewport = renderingEngine.getViewport(this.viewportId)
|
||||||
let imageId = obj.ImageIds[obj.SliceIndex] ? obj.ImageIds[obj.SliceIndex] : obj.ImageIds[0]
|
let imageId = obj.ImageIds[obj.SliceIndex] ? obj.ImageIds[obj.SliceIndex] : obj.ImageIds[0]
|
||||||
@@ -519,7 +572,12 @@ export default {
|
|||||||
if (obj.Modality === 'PT') {
|
if (obj.Modality === 'PT') {
|
||||||
this.cachePTMetadata([image])
|
this.cachePTMetadata([image])
|
||||||
}
|
}
|
||||||
this.prefetchMetadataInformation(obj.ImageIds, obj.Modality)
|
const currentImageIndex = obj.ImageIds[obj.SliceIndex] ? obj.SliceIndex : 0
|
||||||
|
const initialLoadedBytes = this.getImageFileSizeByImageId(imageId)
|
||||||
|
const prefetchImageIds = obj.ImageIds.filter((item, index) => index !== currentImageIndex)
|
||||||
|
if (option.skipInitPrefetch !== true) {
|
||||||
|
this.prefetchMetadataInformation(prefetchImageIds, obj.Modality, initialLoadedBytes, option.limitInitPrefetch === true)
|
||||||
|
}
|
||||||
await viewport.setStack(this.series.Stack, obj.SliceIndex)
|
await viewport.setStack(this.series.Stack, obj.SliceIndex)
|
||||||
this.syncViewportStaticState()
|
this.syncViewportStaticState()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user