feat: 优化dicom 解析速度

This commit is contained in:
mozzie 2024-08-06 09:44:11 +08:00
parent 11790fda94
commit c8c5eff945
2 changed files with 85 additions and 25 deletions

77
electron/core/dicom.ts Normal file
View File

@ -0,0 +1,77 @@
import path from "path";
import * as dicomParser from "dicom-parser";
import fs from "fs";
/**
* .dcm文件
* @param dir
* @param fileList
* @returns
*/
export const findDcmFiles = async (
dir: string,
fileList: string[] = []
): Promise<string[]> => {
const files = await fs.promises.readdir(dir, { withFileTypes: true });
await Promise.all(
files.map(async (file) => {
const filePath = path.join(dir, file.name);
if (file.isDirectory()) {
await findDcmFiles(filePath, fileList); // 递归调用以遍历子目录
} else if (file.name.endsWith(".dcm")) {
fileList.push(filePath); // 如果文件是.dcm文件添加到列表中
}
})
);
return fileList;
};
/**
* dcm文件的metadata信息
*/
export const parseDICOMFile = async (filePath: string) => {
try {
const arrayBuffer = await fs.promises.readFile(filePath);
const byteArray = new Uint8Array(arrayBuffer);
const options = { TransferSyntaxUID: "1.2.840.10008.1.2" };
const dataSet = dicomParser.parseDicom(byteArray, options);
const StudyInstanceUID = dataSet.string("x0020000d");
const SeriesInstanceUID = dataSet.string("x0020000e");
const pixelDataElement = dataSet.elements.x7fe00010;
const pixelData = new Uint16Array(
dataSet.byteArray.buffer,
pixelDataElement.dataOffset,
pixelDataElement.length / 2
);
return {
filePath,
StudyInstanceUID,
SeriesInstanceUID,
pixelData,
};
} catch (error) {
console.error(`Error parsing file ${filePath}:`, error);
}
};
/**
*
* @param filePaths
* @param {number} batchSize
* @returns
*/
export const processFilesInBatches = async (
filePaths: string[],
batchSize: number
) => {
const results = [];
for (let i = 0; i < filePaths.length; i += batchSize) {
const batch = filePaths.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map((filePath) => parseDICOMFile(filePath))
);
results.push(...batchResults);
}
return results;
};

View File

@ -1,34 +1,17 @@
import fs from "fs";
import path from "path";
import * as dicomParser from "dicom-parser"; /* */
import { ipcMain } from "electron";
// 定义一个异步函数来递归地查找.dcm文件
const findDcmFiles = async (
dir: string,
fileList: string[] = []
): Promise<string[]> => {
const files = await fs.promises.readdir(dir, { withFileTypes: true });
await Promise.all(
files.map(async (file) => {
const filePath = path.join(dir, file.name);
if (file.isDirectory()) {
await findDcmFiles(filePath, fileList); // 递归调用以遍历子目录
} else if (file.name.endsWith(".dcm")) {
fileList.push(filePath); // 如果文件是.dcm文件添加到列表中
}
})
);
return fileList;
};
import os from "os";
import { findDcmFiles, processFilesInBatches } from "./core/dicom";
const registerIpcMainHandlers = () => {
ipcMain.on("parseDicom", async (event, file: string) => {
const rootFolder = path.dirname(file);
const fileList = await findDcmFiles(rootFolder);
console.log("rootFolder", rootFolder);
console.log("fileList", fileList);
// event.sender.send("parseDicomResponse", files);
const filePaths = await findDcmFiles(rootFolder);
const batchSize = os.cpus().length * 1 || 10;
console.time("分批处理");
const result = await processFilesInBatches(filePaths, batchSize);
console.timeEnd("分批处理");
});
};