Skip to content

Commit

Permalink
feat: add Rendered Series
Browse files Browse the repository at this point in the history
  • Loading branch information
Chinlinlee committed Nov 20, 2022
1 parent 3dcd205 commit 5d4d09f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 24 deletions.
47 changes: 47 additions & 0 deletions api/dicom-web/controller/WADO-RS/retrieveRenderedSeries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const _ = require("lodash");
const wadoService = require("./service/WADO-RS.service");
const renderedService = require("./service/rendered.service");
const { MultipartWriter } = require("../../../../utils/multipartWriter");
const errorResponse = require("../../../../utils/errorResponse/errorResponseMessage");
const { logger } = require("../../../../utils/log");

/**
*
* @param {import("http").IncomingMessage} req
* @param {import("http").ServerResponse} res
* @returns
*/
module.exports = async function(req, res) {
let headerAccept = _.get(req.headers, "accept", "");
logger.info(`[WADO-RS] [Get study's series' rendered instances, study UID: ${req.params.studyUID}, series UID: ${req.params.seriesUID}]`);
if (!headerAccept == `multipart/related; type="image/jpeg"`) {
let badRequestMessage = errorResponse.getBadRequestErrorMessage(`header accept only allow \`multipart/related; type="image/jpeg"\`, exception : ${headerAccept}`);
res.writeHead(badRequestMessage.HttpStatus, {
"Content-Type": "application/dicom+json"
});
return res.end(JSON.stringify(badRequestMessage));
}

try {
let instancesInStudy = await wadoService.getSeriesImagesPath(req.params);

if (instancesInStudy) {
let multipartWriter = new MultipartWriter([], res, req);

for(let imagePathObj of instancesInStudy) {
let instanceFramesObj = await renderedService.getInstanceFrameObj(imagePathObj);
let dicomNumberOfFrames = _.get(instanceFramesObj, "00280008.Value.0", 1);
dicomNumberOfFrames = parseInt(dicomNumberOfFrames);
await renderedService.writeRenderedImages(req, dicomNumberOfFrames, instanceFramesObj, multipartWriter);
}
multipartWriter.writeFinalBoundary();
}
logger.info(`[WADO-RS] [path: ${req.originalUrl}] [Write Multipart Successfully, study's series' rendered instances, study UID: ${req.params.studyUID}, series UID: ${req.params.seriesUID}]`);
return res.end();
} catch(e) {
res.writeHead(500, {
"Content-Type": "application/dicom+json"
});
res.end(JSON.stringify(e));
}
};
28 changes: 5 additions & 23 deletions api/dicom-web/controller/WADO-RS/retrieveRenderedStudy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ const wadoService = require("./service/WADO-RS.service");
const renderedService = require("./service/rendered.service");
const { MultipartWriter } = require("../../../../utils/multipartWriter");
const errorResponse = require("../../../../utils/errorResponse/errorResponseMessage");
const { logger } = require("../../../../utils/log");
const { logger, apiInfoLog } = require("../../../../utils/log");

/**
*
* @param {import("http").incomingMessage} req
* @param {import("http").IncomingMessage} req
* @param {import("http").ServerResponse} res
* @returns
*/
module.exports = async function(req, res) {
let headerAccept = _.get(req.headers, "accept", "");
logger.info(`[WADO-RS] [Get study's rendered instances, study UID: ${req.params.studyUID}]`);
apiInfoLog("WADO-RS", req.originalUrl, `[Get study's rendered instances, study UID: ${req.params.studyUID}]`);
if (!headerAccept == `multipart/related; type="image/jpeg"`) {
let badRequestMessage = errorResponse.getBadRequestErrorMessage(`header accept only allow \`multipart/related; type="image/jpeg"\`, exception : ${headerAccept}`);
res.writeHead(badRequestMessage.HttpStatus, {
Expand All @@ -32,11 +32,11 @@ module.exports = async function(req, res) {
let instanceFramesObj = await renderedService.getInstanceFrameObj(imagePathObj);
let dicomNumberOfFrames = _.get(instanceFramesObj, "00280008.Value.0", 1);
dicomNumberOfFrames = parseInt(dicomNumberOfFrames);
await writeStudyRenderedImages(req, dicomNumberOfFrames, instanceFramesObj, multipartWriter);
await renderedService.writeRenderedImages(req, dicomNumberOfFrames, instanceFramesObj, multipartWriter);
}
multipartWriter.writeFinalBoundary();
}

apiInfoLog("WADO-RS", req.originalUrl, `[Write Multipart Successfully, study's rendered instances, study UID: ${req.params.studyUID}]`);
return res.end();
} catch(e) {
res.writeHead(500, {
Expand All @@ -45,21 +45,3 @@ module.exports = async function(req, res) {
res.end(JSON.stringify(e));
}
};

async function writeStudyRenderedImages(req, dicomNumberOfFrames, instanceFramesObj, multipartWriter) {
try {
for (let i = 0 ; i < dicomNumberOfFrames; i++) {
let transferSyntax = _.get(instanceFramesObj, "00020010.Value.0");
_.set(req, "params.frameNumber", i+1);
let postProcessResult = await renderedService.postProcessFrameImage(req, instanceFramesObj, transferSyntax);
let buffer = postProcessResult.magick.toBuffer();
multipartWriter.writeBuffer(buffer, {
"Content-Type": "image/jpeg",
"Content-Location": `/dicom-web/studies/${instanceFramesObj.studyUID}/series/${instanceFramesObj.seriesUID}/instances/${instanceFramesObj.instanceUID}/frames/${i+1}/rendered`
});
}
} catch(e) {
console.error(e);
throw e;
}
}
29 changes: 28 additions & 1 deletion api/dicom-web/controller/WADO-RS/service/rendered.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const sharp = require("sharp");
const pythonService = require("../../../../../python");
const dcmtk = require("../../../../../models/DICOM/dcmtk");
const Magick = require("../../../../../models/magick");
const _ = require("lodash");

const { raccoonConfig } = require("../../../../../config-class");
const {
Expand Down Expand Up @@ -203,8 +204,34 @@ async function postProcessFrameImage(req, instanceFramesObj, transferSyntax) {
}
}

/**
*
* @param {import("express").Request} req
* @param {number} dicomNumberOfFrames
* @param {import("../../../../../utils/typeDef/WADO-RS/WADO-RS.def").ImagePathObj} instanceFramesObj
* @param {import("../../../../../utils/multipartWriter").MultipartWriter} multipartWriter
*/
async function writeRenderedImages(req, dicomNumberOfFrames, instanceFramesObj, multipartWriter) {
try {
for (let i = 0 ; i < dicomNumberOfFrames; i++) {
let transferSyntax = _.get(instanceFramesObj, "00020010.Value.0");
_.set(req, "params.frameNumber", i+1);
let postProcessResult = await postProcessFrameImage(req, instanceFramesObj, transferSyntax);
let buffer = postProcessResult.magick.toBuffer();
multipartWriter.writeBuffer(buffer, {
"Content-Type": "image/jpeg",
"Content-Location": `/dicom-web/studies/${instanceFramesObj.studyUID}/series/${instanceFramesObj.seriesUID}/instances/${instanceFramesObj.instanceUID}/frames/${i+1}/rendered`
});
}
} catch(e) {
console.error(e);
throw e;
}
}

module.exports.handleImageQuality = handleImageQuality;
module.exports.handleImageICCProfile = handleImageICCProfile;
module.exports.handleViewport = handleViewport;
module.exports.getInstanceFrameObj = getInstanceFrameObj;
module.exports.postProcessFrameImage = postProcessFrameImage;
module.exports.postProcessFrameImage = postProcessFrameImage;
module.exports.writeRenderedImages = writeRenderedImages;
6 changes: 6 additions & 0 deletions api/dicom-web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ app.get(
require("./controller/WADO-RS/retrieveRenderedStudy")
);

app.get(
"/studies/:studyUID/series/:seriesUID/rendered",
validateParams(renderedQueryValidation, "query", { allowUnknown: false }),
require("./controller/WADO-RS/retrieveRenderedSeries")
);

app.get(
"/studies/:studyUID/series/:seriesUID/instances/:instanceUID/frames/:frameNumber/rendered",
validateParams({
Expand Down

0 comments on commit 5d4d09f

Please sign in to comment.