diff --git a/electron/core/dicom.ts b/electron/core/dicom.ts new file mode 100644 index 0000000..ea96282 --- /dev/null +++ b/electron/core/dicom.ts @@ -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 => { + 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; +}; diff --git a/electron/ipcMainHandlers.ts b/electron/ipcMainHandlers.ts index 8299bc6..2e10d47 100644 --- a/electron/ipcMainHandlers.ts +++ b/electron/ipcMainHandlers.ts @@ -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 => { - 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("分批处理"); }); };