Closed Neuroforge closed 5 years ago
pynetdicom.dsutils.encode()
returns pydicom.filebase.DicomBytesIO
which is just a subclass of io.BytesIO
and keeps it in memory and should be file-like. You can use io.BytesIO.getvalue()
to get bytes
which I assume should be convertible to the byteArray
required by parseDicom
.
Though if you're using pynetdicom you can use event.request.DataSet which is already a io.BytesIO
and skip the unecessary decode/re-encode step (unless you specifically need it for something else).
Awesome. So the event.request. Where is that during the callback on_c_store?
def on_c_store(ds, context, info):
meta = Dataset()
meta.MediaStorageSOPClassUID = ds.SOPClassUID
meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID
meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
meta.TransferSyntaxUID = context.transfer_syntax
# Add the file meta to the dataset
ds.file_meta = meta
ds.is_little_endian = context.transfer_syntax.is_little_endian
ds.is_implicit_VR = context.transfer_syntax.is_implicit_VR
Similar code. https://github.com/pydicom/pynetdicom/issues/45#issuecomment-408580948
Oh, sorry, that's only available for v1.3 and higher with the event-handler system.
The other thing is that I don't think you should be decoding the raw data using utf-8, as utf-8 is a character encoding scheme which is why it throws an exception when it hits a value that doesn't match up with a character code. You should just write the raw binary data to the temp file or whatever.
data = encode(ds, ds.is_implicit_VR, ds.is_little_endian)
with tempfile.TemporaryFile('wb') as tfile:
tfile.write(data)
And if you're just using plain python and javascript I think you're going to have to save the data to disk somewhere.
Thank you for your input.
This is what i am trying now, but it appears that reading it back isn't suitable for cornerstonejs.
fullFilePath = ""
try:
dataJson = self.db.get(fileId)
ds = pickle.loads(dataJson)
transferSyntax = ds.file_meta.TransferSyntaxUID
if transferSyntax == JPEG2000Lossless:
ds.decompress()
fileName = self.getFileNameFromDataSet(ds)
fullFilePath = os.path.join("static/temp", fileName)
ds.save_as(fullFilePath)
with open(fullFilePath, "rb") as tempFile:
byteData = tempFile.read()
return byteData
except Exception as e:
print(e)
pass
finally:
if os.path.exists(fullFilePath):
os.remove(fullFilePath)
Cornerstone error. throw 'dicomParser.readPart10Header: DICM prefix not found at location 132 - this is not a valid DICOM P10 file.';
Have you added the file meta information before trying to encode the dataset?
I was thinking about it a bit more and django should let you mix python and javascript on the server side without having to write to disk. Not sure if django is suitable for your use case though.
Setting the write like original flag to false allows the file to be read to a HttpResponse
def QueryImage(fileId):
.....
fullFilePath = os.path.join("static/temp", fileName)
ds.save_as(fullFilePath, write_like_original=False)
with open(fullFilePath, "rb") as tempFile:
byteData = tempFile.read()
return byteData
Package response with content_type and Content-Disposition.
dataBytes = QueryImage(fileId)
if dataBytes:
response = HttpResponse(
dataBytes, content_type="application/dicom"
)
response["Content-Disposition"] = (
"attachment; filename=" + fileId
)
return response
Javascript can recieve (Using Angular7) as follows
getImages(fileId: string): Observable<any> {
return this.http
.get(`${this.serverURL}/pacs/patient`, {
params: new HttpParams().set('fileId', fileId),
responseType: 'blob',
})
.pipe();
}
Hello,
I am using Pynetdicom to communicate with a PACS. It works well and i can return the dataset objects. Currently, pynetdicom can save the dataset using ds.save_as() but this requires disk reads/writes.
These dataset objects need to be returned to a javascript client as a file object.
Write the bytes to a temp file.
Errors with - 'utf-8' codec can't decode byte 0x80 in position 358: invalid start byte
Is there a way to put the data into a file without saving it to disk? The client side uses Cornerstonejs or Dicomparser.
Options. 1) Write dataset to temporary file, however, not sure how to format dataset correctly as encode/decode creates a byte array that cannot be decoded to a string. 2) Have a method similar to to_json like in pydicom, but not available on pynetdicom for some reason. 3) Encode byte array and return to dicomparser which appears to accept a byte array. (https://github.com/cornerstonejs/dicomParser)
var dataSet = dicomParser.parseDicom(byteArray/*, options */);
There is another thread asking a similar question (https://github.com/pydicom/pynetdicom/issues/300) where it is suggested to json-ify the dataset. However, this won't be opened by Cornerstonejs or DicomParser.