Skip to content

DICOM JSON

DICOM JSON Model(PS3.18 Annex F)是 DICOMweb 说的语言。 dicomjson 包在数据集与它之间双向转换。

go
import "github.com/godicom-dev/godicom/dicomjson"

两个方向

go
jsonData, err := dicomjson.MarshalDataset(ds.Dataset)
parsed, err := dicomjson.ParseDataset(jsonData)

arr, err := dicomjson.MarshalDatasets([]*godicom.Dataset{ds1, ds2})
dss, err := dicomjson.ParseDatasets(arr)
函数用途
MarshalDataset(ds, opts…)一个数据集 → JSON 字节,按标签排序
MarshalDatasetString(ds, opts…)同上,返回 string
MarshalDatasets(dss, opts…)数据集的 JSON 数组 —— 一份 QIDO-RS 结果
ParseDataset(data, opts…)JSON 字节 → *godicom.Dataset
ParseDatasets(data, opts…)JSON 数组 → []*godicom.Dataset
DecodeDataset(r, opts…)直接从 io.Reader
DatasetToMap(ds, opts…)map[string]Element,如果你想在编码前再加工一遍

输出按标签排序,所以对同一个数据集跑两遍会产出逐字节相同的 JSON —— 当你在 diff 夹具或给载荷签名时,这件事的分量比听起来大。

元素的形状

go
type Element struct {
	VR           string            `json:"vr"`
	Value        []json.RawMessage `json:"Value,omitempty"`
	InlineBinary string            `json:"InlineBinary,omitempty"`
	BulkDataURI  string            `json:"BulkDataURI,omitempty"`
}

Value 保持为 json.RawMessage,所以一个以 1.0 进来的数不会在中途变成 1

大块数据

一个 20 MB 的 Pixel Data 元素做 base64 内联,技术上是合法 JSON,实际上是个错误。超过某个阈值就改为输出一个引用:

go
jsonData, err := dicomjson.MarshalDataset(ds.Dataset,
	dicomjson.WithBulkDataThreshold(1024),
	dicomjson.WithBulkDataURIBuilder(func(t godicom.Tag, vr godicom.VR, value []byte) (string, error) {
		return store(t, value) // return the URI you stored it at
	}),
)

读回来的时候再解析它们:

go
parsed, err := dicomjson.ParseDataset(jsonData,
	dicomjson.WithBulkDataURIReader(func(t godicom.Tag, vr godicom.VR, uri string) ([]byte, error) {
		return fetch(uri)
	}),
)

阈值以下的值以 base64 装在 InlineBinary 里。没有设 builder 时,什么都不会被外置。

无法 marshal 的元素

WithSuppressInvalidTags() 会丢掉 marshal 失败的元素,而不是让整份文档失败。当你从不受自己控制的文件里导出、而一个坏元素不该让你连带丢掉另外四百个时,用它:

go
jsonData, err := dicomjson.MarshalDataset(ds.Dataset, dicomjson.WithSuppressInvalidTags())

不用它的话,marshal 错误会被返回 —— 这是正确的默认,因为悄悄丢一个元素正是那种半年后才发现的事。

与 DICOMweb 一起

gonetdicom 的 DICOMweb 客户端对 WADO-RS 和 QIDO-RS 事务已经返回解析好的 metadata,所以通常只有在你自己构造载荷或实现服务端时,才会直接去用 dicomjson

基于 MIT 许可证发布。