Skip to content

Commit

Permalink
Add support for render png and quality paramater for jpeg (#2576)
Browse files Browse the repository at this point in the history
  • Loading branch information
abdullah248 authored Apr 27, 2023
1 parent a6baec9 commit 821af41
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 47 deletions.
14 changes: 8 additions & 6 deletions src/Microsoft.Health.Dicom.Api/Controllers/RetrieveController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public async Task<IActionResult> GetInstanceAsync(
return CreateResult(response);
}

[Produces(KnownContentTypes.ImageJpeg)]
[Produces(KnownContentTypes.ImageJpeg, KnownContentTypes.ImagePng)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.NoContent)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.BadRequest)]
Expand All @@ -166,12 +166,13 @@ public async Task<IActionResult> GetInstanceAsync(
public async Task<IActionResult> GetRenderedInstanceAsync(
string studyInstanceUid,
string seriesInstanceUid,
string sopInstanceUid)
string sopInstanceUid,
[FromQuery] int quality = 100)
{
_logger.LogInformation("DICOM Web Retrieve Rendered Image Transaction request for instance received");

RetrieveRenderedResponse response = await _mediator.RetrieveRenderedDicomInstanceAsync(
studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, HttpContext.Request.GetAcceptHeaders(), HttpContext.RequestAborted);
studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, HttpContext.Request.GetAcceptHeaders(), quality, HttpContext.RequestAborted);

return CreateResult(response);
}
Expand Down Expand Up @@ -223,7 +224,7 @@ public async Task<IActionResult> GetFramesAsync(
return CreateResult(response);
}

[Produces(KnownContentTypes.ImageJpeg)]
[Produces(KnownContentTypes.ImageJpeg, KnownContentTypes.ImagePng)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.NoContent)]
[ProducesResponseType(typeof(string), (int)HttpStatusCode.BadRequest)]
Expand All @@ -237,12 +238,13 @@ public async Task<IActionResult> GetRenderedFrameAsync(
string studyInstanceUid,
string seriesInstanceUid,
string sopInstanceUid,
int frame)
int frame,
[FromQuery] int quality = 100)
{
_logger.LogInformation("DICOM Web Retrieve Rendered Image Transaction request for frame received");

RetrieveRenderedResponse response = await _mediator.RetrieveRenderedDicomInstanceAsync(
studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, HttpContext.Request.GetAcceptHeaders(), HttpContext.RequestAborted, frame);
studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, HttpContext.Request.GetAcceptHeaders(), quality, HttpContext.RequestAborted, frame);

return CreateResult(response);
}
Expand Down
6 changes: 4 additions & 2 deletions src/Microsoft.Health.Dicom.Client/DicomWebClient.Retrieve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public async Task<DicomWebResponse<Stream>> RetrieveRenderedInstanceAsync(
string studyInstanceUid,
string seriesInstanceUid,
string sopInstanceUid,
int quality = 100,
string mediaType = DicomWebConstants.ImageJpegMediaType,
string partitionName = default,
CancellationToken cancellationToken = default)
Expand All @@ -109,7 +110,7 @@ public async Task<DicomWebResponse<Stream>> RetrieveRenderedInstanceAsync(
EnsureArg.IsNotNullOrWhiteSpace(sopInstanceUid, nameof(sopInstanceUid));

return await RetrieveRenderedAsync(
GenerateRequestUri(string.Format(CultureInfo.InvariantCulture, DicomWebConstants.BaseRetrieveInstanceRenderedUriFormat, studyInstanceUid, seriesInstanceUid, sopInstanceUid), partitionName),
GenerateRequestUri(string.Format(CultureInfo.InvariantCulture, DicomWebConstants.BaseRetrieveInstanceRenderedUriFormat, studyInstanceUid, seriesInstanceUid, sopInstanceUid, quality), partitionName),
mediaType,
cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -162,6 +163,7 @@ public async Task<DicomWebResponse<Stream>> RetrieveRenderedFrameAsync(
string seriesInstanceUid,
string sopInstanceUid,
int frame,
int quality = 100,
string mediaType = DicomWebConstants.ImageJpegMediaType,
string partitionName = default,
CancellationToken cancellationToken = default)
Expand All @@ -171,7 +173,7 @@ public async Task<DicomWebResponse<Stream>> RetrieveRenderedFrameAsync(
EnsureArg.IsNotNullOrWhiteSpace(sopInstanceUid, nameof(sopInstanceUid));

return await RetrieveRenderedAsync(
GenerateRequestUri(string.Format(CultureInfo.InvariantCulture, DicomWebConstants.BaseRetrieveFrameRenderedUriFormat, studyInstanceUid, seriesInstanceUid, sopInstanceUid, frame), partitionName),
GenerateRequestUri(string.Format(CultureInfo.InvariantCulture, DicomWebConstants.BaseRetrieveFrameRenderedUriFormat, studyInstanceUid, seriesInstanceUid, sopInstanceUid, frame, quality), partitionName),
mediaType,
cancellationToken).ConfigureAwait(false);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.Health.Dicom.Client/DicomWebConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public static class DicomWebConstants
public const string BaseSeriesUriFormat = BaseStudyUriFormat + "/series/{1}";
public const string BaseRetrieveSeriesMetadataUriFormat = BaseSeriesUriFormat + "/metadata";
public const string BaseInstanceUriFormat = BaseSeriesUriFormat + "/instances/{2}";
public const string BaseRetrieveInstanceRenderedUriFormat = BaseInstanceUriFormat + "/rendered";
public const string BaseRetrieveInstanceRenderedUriFormat = BaseInstanceUriFormat + "/rendered?quality={3}";
public const string BaseRetrieveInstanceThumbnailUriFormat = BaseInstanceUriFormat + "/thumbnail";
public const string BaseRetrieveInstanceMetadataUriFormat = BaseInstanceUriFormat + "/metadata";
public const string BaseRetrieveFramesUriFormat = BaseInstanceUriFormat + "/frames/{3}";
public const string BaseRetrieveFrameRenderedUriFormat = BaseRetrieveFramesUriFormat + "/rendered";
public const string BaseRetrieveFrameRenderedUriFormat = BaseRetrieveFramesUriFormat + "/rendered?quality={4}";
public const string BaseRetrieveFramesThumbnailUriFormat = BaseRetrieveFramesUriFormat + "/thumbnail";
public const string PartitionsUriString = "/partitions";
public const string StudiesUriString = "/studies";
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.Health.Dicom.Client/IDicomWebClient.Retrieve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public partial interface IDicomWebClient
{
Task<DicomWebResponse<Stream>> RetrieveSingleFrameAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int frame, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebAsyncEnumerableResponse<Stream>> RetrieveFramesAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int[] frames = default, string mediaType = DicomWebConstants.ApplicationOctetStreamMediaType, string dicomTransferSyntax = DicomWebConstants.OriginalDicomTransferSyntax, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebResponse<Stream>> RetrieveRenderedFrameAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int frame, string mediaType = DicomWebConstants.ImageJpegMediaType, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebResponse<Stream>> RetrieveRenderedFrameAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int frame, int quality = 100, string mediaType = DicomWebConstants.ImageJpegMediaType, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebResponse<DicomFile>> RetrieveInstanceAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, string dicomTransferSyntax = DicomWebConstants.OriginalDicomTransferSyntax, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebResponse<Stream>> RetrieveRenderedInstanceAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, string mediaType = DicomWebConstants.ImageJpegMediaType, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebResponse<Stream>> RetrieveRenderedInstanceAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int quality = 100, string mediaType = DicomWebConstants.ImageJpegMediaType, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebAsyncEnumerableResponse<DicomDataset>> RetrieveInstanceMetadataAsync(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, string ifNoneMatch = default, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebAsyncEnumerableResponse<DicomFile>> RetrieveSeriesAsync(string studyInstanceUid, string seriesInstanceUid, string dicomTransferSyntax = DicomWebConstants.OriginalDicomTransferSyntax, string partitionName = default, CancellationToken cancellationToken = default);
Task<DicomWebAsyncEnumerableResponse<DicomDataset>> RetrieveSeriesMetadataAsync(string studyInstanceUid, string seriesInstanceUid, string ifNoneMatch = default, string partitionName = default, CancellationToken cancellationToken = default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task GivenARequestWithInvalidStudyInstanceIdentifier_WhenHandlerIsE
string seriesInstanceUid = TestUidGenerator.Generate();
string sopInstanceUid = TestUidGenerator.Generate();

RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, new[] { AcceptHeaderHelpers.CreateRenderJpegAcceptHeader() });
RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, 75, new[] { AcceptHeaderHelpers.CreateRenderAcceptHeader() });
var ex = await Assert.ThrowsAsync<InvalidIdentifierException>(() => _retrieveRenderedHandler.Handle(request, CancellationToken.None));
Assert.Equal(ValidationErrorCode.UidIsInvalid, ex.ErrorCode);
}
Expand All @@ -58,7 +58,7 @@ public async Task GivenARequestWithInvalidSeriesInstanceIdentifier_WhenHandlerIs
string studyInstanceUid = TestUidGenerator.Generate();
string sopInstanceUid = TestUidGenerator.Generate();

RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, new[] { AcceptHeaderHelpers.CreateRenderJpegAcceptHeader() });
RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, 75, new[] { AcceptHeaderHelpers.CreateRenderAcceptHeader() });
var ex = await Assert.ThrowsAsync<InvalidIdentifierException>(() => _retrieveRenderedHandler.Handle(request, CancellationToken.None));
Assert.Equal(ValidationErrorCode.UidIsInvalid, ex.ErrorCode);
}
Expand All @@ -73,7 +73,7 @@ public async Task GivenARequestWithInvalidInstanceInstanceIdentifier_WhenHandler
string studyInstanceUid = TestUidGenerator.Generate();
string seriesInstanceUid = TestUidGenerator.Generate();

RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, new[] { AcceptHeaderHelpers.CreateRenderJpegAcceptHeader() });
RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Instance, 0, 75, new[] { AcceptHeaderHelpers.CreateRenderAcceptHeader() });
var ex = await Assert.ThrowsAsync<InvalidIdentifierException>(() => _retrieveRenderedHandler.Handle(request, CancellationToken.None));
Assert.Equal(ValidationErrorCode.UidIsInvalid, ex.ErrorCode);
}
Expand All @@ -88,7 +88,7 @@ public async Task GivenARequestWithInvalidFramNumber_WhenHandlerIsExecuted_ThenB
string seriesInstanceUid = TestUidGenerator.Generate();
string sopInstanceUid = TestUidGenerator.Generate();

RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, frame, new[] { AcceptHeaderHelpers.CreateRenderJpegAcceptHeader() });
RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, frame, 75, new[] { AcceptHeaderHelpers.CreateRenderAcceptHeader() });
var ex = await Assert.ThrowsAsync<BadRequestException>(() => _retrieveRenderedHandler.Handle(request, CancellationToken.None));
Assert.Equal(error, ex.Message);
}
Expand All @@ -100,7 +100,7 @@ public async Task GivenARequestWithValidInstanceInstanceIdentifier_WhenHandlerIs
string seriesInstanceUid = TestUidGenerator.Generate();
string sopInstanceUid = TestUidGenerator.Generate();

RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, 5, new[] { AcceptHeaderHelpers.CreateRenderJpegAcceptHeader() });
RetrieveRenderedRequest request = new RetrieveRenderedRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, ResourceType.Frames, 5, 75, new[] { AcceptHeaderHelpers.CreateRenderAcceptHeader() });
await _retrieveRenderedHandler.Handle(request, CancellationToken.None);
}

Expand Down
Loading

0 comments on commit 821af41

Please sign in to comment.