I'm trying to read a png encoded image in memory and create a dicom file with it. I have scoured the internet and this board for a proper example but no success so I tried to break down the problem and to see if I can get it to work from a file on disk....also not so successful. The DICOM file gets created and I can upload it to the PACS/DICOM server but when I view the image in the Osimis Webviewer I see garbage. In the code below I have left out the irrelevant code lines.
I dont know the PNG format in detail, but it's not possible to simply copy a PNG bitstream to a DICOM dataset's Pixel Data element and create a valie DICOM image from it.
DCMTK (if this is part of your question?) has a tool called img2dcm that creates DICOM files from JPEG and BMP. Probably you can decompress your PNG and bring it into BMP format, for example, and then use the img2dcm code to make valid DICOM image out of it. JPEG and BMP handling is handled in plugins, so you could also write a plugin that handles PNG as input format directly.
what if I convert my png to jpg ( in memory ) will that work with the current state of dcmtk and the jpeg plugin? The tool img2dcm is an application and I want everything done in my C++ code without invoking external processes. Once I have a proof of concept that it works, I might look in to building a png plugin.
yes, I think it should work in memory, though image2dcm and the underlying classes (as the input plugins) usually work on files and therefore the I2DJpegSource plugin might need adaptations (i.e. derive from it or in the worst case copy it and modify methods as necessary).
The general flow is that you instantiate class Image2Dcm and call convert() on it. convert() requires you to hand in input and output plugin. Hand in your own derived JPEG plugin (see above) that uses pixel data from memory instead of from file and you should be fine.
OFCondition result is OK but my dicom file is 1kb, so no image data. If I use the command line tool img2dcm.exe with this image I get a correct dicom file. Can you tell me what I'm doing wrong?
I tried the writeXfer parameter ( value is by the way : EXS_JPEGProcess1 ) in the savefile function instead of EXS_LittleEndianExplicit but my dicom file is still 1 kb. I also tried to compress the dataset AFTER the covert by
do you actually feed your "dataset" into the "fileformat"? Otherwise you will write a file without dataset.
See how it's done in img2dcm. Applied to your code this would be something like:
but what I also found out is that "size" is just 4 in the code below, that might be the cause but I don't understand why ( code is not nicely written but bare with me please )
The convert() call returns a newly allocated dataset, and does not use the empty one (created by DcmFileFormat internally) that you provide in your version of the code.
Also, pixel data can contain \0 bytes, so using strlen doesnt seem to be a good idea to me. The value you look for (number of bytes in "pixdata") should be in "length" aftr calling readPixelData().
Michael, thanks that did the trick. Is this designed behavior or a bug ? I would expect that if you have a pointer to a DcmDataset object and pass it to convert() it would modify the object pointed to not completely reset it.... right??
I consider the allocation in convert() a feature Since the parameter is a reference to a pointer, this is usually a sufficient note to the user that the method returns a new pointer for newly allocated memory. There is no reason to make it a reference if one does not return a new pointer.
I added a short note to the existing API documentation of convert() that hopefully makes it more obvious. The related commit will be online within the next days.