I am using python 3.6 on Windows to fetch a DICOM file from a database as a string of bytes. Now, I would like to use the Pydicom
library to read the content of the file. The dcmread()
method takes a file-like object as main argument, however the following piece of code raises an error when trying to access the stored images :
import sqlite3 as sql, io
...
dicom_as_bytes = cursor.fetchone()[0] # read bytes from sqlite3 request
dicom_as_bytes = io.BytesIO(dicom_as_bytes) # convert to file-like format
dcm_file = dcmread(dicom_as_bytes)
images = dcm_file.pixel_array # PermissionError: [Errno 13] Permission denied: 'C:\\Users\\<User>\\AppData\\Local\\Temp\\tmpfhvgc2oo'
There is no problem with the sql request in itself because I was able to write to a persistent file and read it :
tmp_file = open("tmp", "wb")
tmp_file.write(dicom_as_bytes)
tmp_file.close()
dcm_file = dcmread("tmp")
images = dcm_file.pixel_array # no error
Free anonymized DICOM files can be found on the Internet with a bit of search. As I am not sure I have the right to link the one I used, I won't post a link here - sorry.
Here is the pydicom
documentation of the dcmread
method : link
The above method is working. However, I would prefer to avoid creating a temporary file in the project folder like that. I also took a look at python's tempfile library which doesn't seem to work for me as well, for one reason or another :
import tempfile
tmp_file = tempfile.NamedTemporaryFile()
temp_file.write(dicom_as_bytes)
temp_file.seek(0)
dcm_file = dcmread(temp_file)
images = dcm_file.pixel_array # TypeError: GDCM could not read DICOM image
temp_file.close()
In the end, I would like to know if it is possible to use BytesIO
or tempfile
to load the images of a DICOM file from sqlite3
bytes of data corresponding exactly to sqlite3.Binary(open("file.dcm", "rb).read())
with "file.dcm"
a DICOM file storing more than one image. I would prefer to not use a temporary file explicitely because I should have no reason to use temporary files (no lack of memory, storage space, I am not working on inter-process communication or crash recovery either).
I am wondering if there is a need to somehow encode the received bytes before creating a new BytesIO
object or writing to a TemporaryFile
. However, this doesn't seem to be the case because I can just write them directly in a file with open(filename, mode).write(dicom_bytes)
or TemporaryFile().write(dicom_bytes)
. It's just that on the one hand, I can access the image array but not on the other (although I can access basic information such as dcm_file.filename
without an issue). Maybe converting a BytesIO
object to a FileIO
object would work, although I have no idea how to do that without creating a new file with open
.