const parser = require('dicom-parser'); const fsp = require('fs-promise'); const iconv = require("iconv-lite") const filePath = '/Users/fuyu/DX/837DCB82.dcm'; // const filePath = '/Users/fuyu/Desktop/MR/MR1912090041/1.2.392.200036.9125.2.138612190166.20191209000532/517D6718/7F8E6EC3.dcm'; // const filePath = '/Users/fuyu/Downloads/5805957747722467ffe1bbbf31e81a1c'; // const filePath = '/Users/fuyu/Downloads/d1137941cbce83e442eb2978989d059c'; // const filePath = '/Users/fuyu/Downloads/7380ed924937d0aee73be14f32f75706'; let test = async url => { const fileBuffer = await fsp.readFile(url); const dataSet = parser.parseDicom(fileBuffer); const patientName = dataSet.string(patientTag.patientName) // console.log(iconv.decode(patientName, 'UTF-8')) const charset = getCharSet(dataSet) console.log(patientName, iconv.decode(patientName, 'GB2312'), charset) // console.log(dataSet.string('x00080005')); // [patientTag, studyTag, seriesTag, imageTag].forEach(tags => { // for (let key in tags) { // console.log(key, dataSet.string(tags[key])) // } // }) // const charset = getCharSet(dataSet) // const originalString = dataSet.string; // dataSet.string = (tag, index) => { // let value = originalString.call(dataSet, tag, index); // if (value != null && value != 'undefined') { // console.log('charset', charset) // let _value = iconv.decode(value, 'UTF-8'); // // console.log() // if (_value != null && _value != 'undefined') { // return _value.replace(/['^']+/g, '') // } // return _value; // } else { // return value; // } // }; // let text = dataSet.string('x0008103e') // console.log(text, iconv.decode(text, 'ISO_IR 100')) } const chatSetMap = { 'ISO_IR 6': 'UTF-8', 'ISO_IR 192': 'UTF-8', 'ISO_IR 100': 'ISO-8859-1', 'ISO_IR 101': 'ISO-8859-2', 'ISO_IR 109': 'ISO-8859-3', 'ISO_IR 110': 'ISO-8859-4', 'ISO_IR 144': 'ISO-8859-5', 'ISO_IR 127': 'ISO-8859-6', 'ISO_IR 126': 'ISO-8859-7', 'ISO_IR 138': 'ISO-8859-8', 'ISO_IR 148': 'ISO-8859-9', } const getCharSet = dataSet => { let specificCharacterSet = dataSet.string('x00080005'); console.log(specificCharacterSet, 'specificCharacterSet') let charset = 'GB2312' if (specificCharacterSet) { charset = chatSetMap[specificCharacterSet] || charset } return charset } // GB2312 // //xml文件编码方式,以支持中文显示。 // if (!csetString.empty()) // encString = "GB2312"; test(filePath) const patientTag = { 'patientName': 'x00100010', //患者姓名 PN 'patientId': 'x00100020', //患者ID LO 'birthDate': 'x00100030', //患者出生日期 DA 'birthTime': 'x00100032', //患者出生时间 TM 'patientSex': 'x00100040', //患者性别 CS 'pregnancy': 'x001021c0', //怀孕状态 US 'weight': 'x00101030', //患者体重 DS 'institutionName': 'x00080080', //生产厂家 US 'institutionCode': 'x00080082', //生产厂家代码 US 'patientAge': 'x00101010' //做检查时刻的患者年龄 AS }; // 'patientName': { // 'tag': 'x00100010', // 'vr': 'PN', // 'description': 'Patient’s Name', // 'comment': '患者姓名' // }, //患者姓名 PN const studyTag = { 'accessionNumber': 'x00080050', //检查号(RIS的生成序号) SH 'studyId': 'x00200010', //检查ID SH 'studyUid': 'x0020000d', //检查实例号 唯一标记 UI 'studyDate': 'x00080020', //检查日期(检查开始的日期) DA 'studyTime': 'x00080030', //检查时间(检查开始的时间) TM 'modalities': 'x00080061', //一个检查中含有的不同检查类型 CS 'partExamined': 'x00080015', //检查的部位 CS 'description': 'x00081030', //检查的描述 LO 'patientAge': 'x00101010', //做检查时刻的患者年龄 AS 'institutionName': 'x00080080', //生产厂家 US 'institutionCode': 'x00080082', //生产厂家代码 US }; const seriesTag = { 'seriesNumber': 'x00200011', //序列号:识别不同检查的号码. 'seriesUid': 'x0020000e', //序列实例号:唯一标记不同序列的号码. 'modality': 'x00080060', //检查模态(MRI/CT/CR/DR) 'description': 'x0008103e', //检查描述和说明 'seriesDate': 'x00080021', //检查日期 'seriesTime': 'x00080031', //检查时间 'imagePosition': 'x00200032', //图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标. 'imageOrientation': 'x00200037', //图像方位: 'sliceThickness': 'x00180050', //层厚 'spacingSlices': 'x00180088', //层与层之间的间距,单位为mm 'sliceLocation': 'x00201041', //实际的相对位置,单位为mm. 'MRAcquisition': 'x00180023', // 'partExamined': 'x00180015', //身体部位. }; const imageTag = { 'imageType': 'x00080008', //图片类型 CS 'imageId': 'x00080018', //实例UID 'contentDate': 'x00080023', //影像拍摄的日期 DA 'contentTime': 'x00080033', //影像拍摄的时间 TM 'imageNumber': 'x00200013', //图像码 IS 'pixel': 'x00280002', //图像上的采样率. US 'rows': 'x00280010', //图像的总行数,行分辨率 US 'columns': 'x00280011', //图像的总列数,列分辨率 US 'pixelSpacing': 'x00280030', //像素间距(像素中心之间的物理间距) DS 'bitsStored': 'x00280101', //存储的位数:有12到16列举值.存储每一个像素用的位数.每一个样本应该有相同值. 'highBit': 'x00280102', //高位. DS 'pixelRepresentation': 'x00280103', //像素数据的表现类型:这是一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整数,0001H = 2的补码. DS 'windowCenter': 'x00281050', //窗位 DS 'windowWidth': 'x00281051', //窗宽 DS 'rescaleIntercept': 'x00281052', //截距:如果表明不同模态的LUT颜色对应表不存在时,则使用方程Units = m*SV + b,计算真实的像素值到呈现像素值。其中这个值为表达式中的b 'rescaleSlope': 'x00281053', //斜率.这个值为表达式中的m。 'rescaleType': 'x00281054', //输出值的单位.这是一个枚举值, 'imagePosition': 'x00200032', //图像位置 DS 'imageOrientation': 'x00200037', //图像方位 DS 'SOPInstanceUID': 'x00080018', //图像方位 DS 'numberOfFrames': 'x00280008', //图像frame张数 DS 'cineRate': 'x00180040' //图像播放速率 } /** Image Tag*/ //00080008 Image Type 图片类型 CS //00080018 SOP Instance UID SOP实例UID //00080023 Content Date 影像拍摄的日期 DA //00080033 Content Time 影像拍摄的时间. TM //00200013 Image/Instance Number 图像码(辨识图像的号码) IS //00280002 Samples Per Pixel 图像上的采样率. US /** * MONOCHROME1,MONOCHROME2. * 用来判断图像是否是彩色的, * MONOCHROME1/2是灰度图, * RGB则是真彩色图,还有其他. */ //00280004 Photometric Interpretation: 光度计的解释,对于CT图像,用两个枚举值 CS //00280010 Rows 图像的总行数,行分辨率. US //00280011 Columns 图像的总列数,列分辨率. US //00280030 Pixel Spacing 像素间距(像素中心之间的物理间距) DS //00280100 Bits Allocated 分配的位数(存储每一个像素值时分配的位数) US //00280101 Bits Stored: 存储的位数(有12到16列举值 US //00280102 High Bit 高位 US //00280103 Pixel Representation 像素数据的表现类型(枚举值,分别为十六进制数0000和0001) US //00281050 Window Center 窗位 DS //00281051 Window Width 窗宽 DS //00281052 Rescale Intercept 截距 DS //00281053 Rescale Slope 斜率 DS //00281054 Rescale Type 输出值的单位 LO /**图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标*/ //00200032 Image Position 图像位置 DS //00200037 Image Orientation 图像方位 DS //00180050 Slice Thickness 层厚 DS //00180088 Spacing Between Slices 层与层之间的间距,单位为mm DS //00201041 Slice Location 实际的相对位置,单位为mm. DS //00180023 MR Acquisition CS //00180015 Body Part Examined 身体部位 CS const patientWADO = { 'patientName': ['00100010', 'PN'], //患者姓名 PN 'patientId': ['00100020', 'LO'], //患者ID LO 'birthDate': ['00100030', 'DA'], //患者出生日期 DA 'birthTime': ['00100032', 'TM'], //患者出生时间 TM 'patientSex': ['00100040', 'CS'], //患者性别 CS 'pregnancy': ['001021c0', 'US'], //怀孕状态 US 'weight': ['00101030', 'DS'], //患者体重 DS 'institutionName': ['00080080', 'US'], //生产厂家 US 'institutionCode': ['00080082', 'US'], //生产厂家代码 US 'patientAge': ['00101010', 'AS'] //做检查时刻的患者年龄 AS } const studyWADO = { 'accessionNumber': ['00080050', 'SH'], //检查号(RIS的生成序号) SH 'studyId': ['00200010', 'SH'], //检查ID SH 'studyUid': ['0020000d', 'UI'], //检查实例号 唯一标记 UI 'studyDate': ['00080020', 'DA'], //检查日期(检查开始的日期) DA 'studyTime': ['00080030', 'TM'], //检查时间(检查开始的时间) TM 'modalities': ['00080061', 'CS'], //一个检查中含有的不同检查类型 CS 'partExamined': ['00080015', 'CS'], //检查的部位 CS 'description': ['00081030', 'LO'], //检查的描述 LO 'patientAge': ['00101010', 'AS'] //做检查时刻的患者年龄 AS } const seriesWADO = { 'seriesNumber': ['00200011', 'IS'], //序列号:识别不同检查的号码. 'seriesUid': ['0020000e', 'UI'], //序列实例号:唯一标记不同序列的号码. 'modality': ['00080060', 'CS'], //检查模态(MRI/CT/CR/DR) 'description': ['0008103e', 'LO'], //检查描述和说明 'seriesDate': ['00080021', 'DA'], //检查日期 'seriesTime': ['00080031', 'DA'], //检查时间 'imagePosition': ['00200032', 'DS'], //图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标. 'imageOrientation': ['00200037', 'DS'], //图像方位: 'sliceThickness': ['00180050', 'DS'], //层厚 'spacingSlices': ['00180088', 'DS'], //层与层之间的间距,单位为mm 'sliceLocation': ['00201041', 'DS'], //实际的相对位置,单位为mm. 'MRAcquisition': ['00180023', 'CS'], // 'partExamined': ['00180015', 'CS'], //身体部位. }; const imageWADO = { 'imageType': ['00080008', 'CS'], //图片类型 CS 'imageId': ['00080018', 'UI'], //实例UID UI 'contentDate': ['00080023', 'DA'], //影像拍摄的日期 DA 'contentTime': ['00080033', 'TM'], //影像拍摄的时间 TM 'imageNumber': ['00200013', 'IS'], //图像码 IS 'pixel': ['00280002', 'US'], //图像上的采样率. US 'rows': ['00280010', 'US'], //图像的总行数,行分辨率 US 'columns': ['00280011', 'US'], //图像的总列数,列分辨率 US 'pixelSpacing': ['00280030', 'DS'], //像素间距(像素中心之间的物理间距) DS 'bitsStored': ['00280101', 'US'], //存储的位数:有12到16列举值.存储每一个像素用的位数.每一个样本应该有相同值. US 'highBit': ['00280102', 'DS'], //高位. DS 'pixelRepresentation': ['00280103', 'DS'], //像素数据的表现类型:这是一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整数,0001H = 2的补码. DS 'windowCenter': ['00281050', 'DS'], //窗位 DS 'windowWidth': ['00281051', 'DS'], //窗宽 DS 'rescaleIntercept': ['00281052', 'DS'], //截距:如果表明不同模态的LUT颜色对应表不存在时,则使用方程Units = m*SV + b,计算真实的像素值到呈现像素值。其中这个值为表达式中的b 'rescaleSlope': ['00281053', 'DS'], //斜率.这个值为表达式中的m。 'rescaleType': ['00281054', 'DS'], //输出值的单位.这是一个枚举值, 'imagePosition': ['00200032', 'DS'], //图像位置 DS 'imageOrientation': ['00200037', 'DS'], //图像方位 DS 'SOPInstanceUID': ['00080018', 'DS'], //图像方位 'numberOfFrames': ['00280008', 'IS'] //图像frame张数 DS } // export { // patientTag, // studyTag, // seriesTag, // imageTag, // patientWADO, // studyWADO, // seriesWADO, // imageWADO // } // tag VR VM Description // 00080005 CS 1-n SpecificCharacterSet // 00080020 DA 1-1 StudyDate // 00080030 TM 1-1 StudyTime // 00080050 SH 1-1 Accession​Numbe // 00080056 CS 1-1 Instance​Availability // 00080061 CS 1-n Modalities​In​Study // 00080090 PN 1-1 Referring​Physician​Name // 00081190 UR 1-1 Retrieve​URL // 00090010 LO 1-1 SpecificCharacterSet // 00091002 UN 1-1 SpecificCharacterSet // 00100010 PN 1-1 Patient​Name // 00100020 LO 1-1 Patient​Id // 00100021 LO 1-1 Issuer​Of​Patient​ID // 00100030 DT 1-1 Patient​Birth​Date // 00100040 CS 1-1 Patient​Sex // 00101002 SQ 1-1 Other​Patient​IDs​Sequence // 0020000D UI 1-1 Study​Instance​UID // 00200010 SH 1-1 Study​ID // 00201206 IS 1-1 Number​Of​Study​Related​Series // 00201208 IS 1-1 Number​Of​Study​Related​Instances // { // Result 1 // "00080005": { // "vr": "CS", // "Value": [ "ISO_IR 192" ] // }, // "00080020": { // "vr": "DT", // "Value": [ "20130409" ] // }, // "00080030": { // "vr": "TM", // "Value": [ "131600.0000" ] // }, // "00080050": { // "vr": "SH", // "Value": [ "11235813" ] // }, // "00080056": { // "vr": "CS", // "Value": [ "ONLINE" ] // }, // "00080061": { // "vr": "CS", // "Value": [ // "CT", // "PET" // ] // }, // "00080090": { // "vr": "PN", // "Value": [ // { // "Alphabetic": "^Bob^^Dr." // } // ] // }, // "00081190": { // "vr": "UR", // "Value": [ "http://wado.nema.org/studies/ // 1.2.392.200036.9116.2.2.2.1762893313.1029997326.945873" ] // }, // "00090010": { // "vr": "LO", // "Value": [ "Vendor A" ] // }, // "00091002": { // "vr": "UN", // "InlineBinary": [ "z0x9c8v7" ] // }, // "00100010": { // "vr": "PN", // "Value": [ // { // "Alphabetic": "Wang^XiaoDong", // "Ideographic": "王^小東" // } // ] // }, // "00100020": { // "vr": "LO", // "Value": [ "12345" ] // }, // "00100021": { // "vr": "LO", // "Value": [ "Hospital A" ] // }, // "00100030": { // "vr": "DT", // "Value": [ "19670701" ] // }, // "00100040": { // "vr": "CS", // "Value": [ "M" ] // }, // "00101002": { // "vr": "SQ", // "Value": [ // { // "00100020": { // "vr": "LO", // "Value": [ "54321" ] // }, // "00100021": { // "vr": "LO", // "Value": [ "Hospital B" ] // } // }, // { // "00100020": { // "vr": "LO", // "Value": [ "24680" ] // }, // "00100021": { // "vr": "LO", // "Value": [ "Hospital C" ] // } // } // ] // }, // "0020000D": { // "vr": "UI", // "Value": [ "1.2.392.200036.9116.2.2.2.1762893313.1029997326.945873" ] // }, // "00200010": { // "vr": "SH", // "Value": [ "11235813" ] // }, // "00201206": { // "vr": "IS", // "Value": [ 4 ] // }, // "00201208": { // "vr": "IS", // "Value": [ 942 ] // } // }