/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /* * This example shows how to setup the pipeline from a gdcm::ImageReader into a * Qt QImage data structure. * It only handles 2D image. * * Ref: * http://doc.trolltech.com/4.5/qimage.html * * Usage: * ConvertToQImage gdcmData/012345.002.050.dcm output.png * Thanks: * Sylvain ADAM (sylvain51 hotmail com) for contributing this example */ #include "gdcmImageReader.h" #include #include bool ConvertToFormat_RGB888(gdcm::Image const & gimage, char *buffer, QImage* &imageQt) { const unsigned int* dimension = gimage.GetDimensions(); unsigned int dimX = dimension[0]; unsigned int dimY = dimension[1]; gimage.GetBuffer(buffer); // Let's start with the easy case: if( gimage.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::RGB ) { if( gimage.GetPixelFormat() != gdcm::PixelFormat::UINT8 ) { return false; } unsigned char *ubuffer = (unsigned char*)buffer; // QImage::Format_RGB888 13 The image is stored using a 24-bit RGB format (8-8-8). imageQt = new QImage((unsigned char *)ubuffer, dimX, dimY, 3*dimX, QImage::Format_RGB888); } else if( gimage.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::MONOCHROME2 ) { if( gimage.GetPixelFormat() == gdcm::PixelFormat::UINT8 ) { // We need to copy each individual 8bits into R / G and B: unsigned char *ubuffer = new unsigned char[dimX*dimY*3]; unsigned char *pubuffer = ubuffer; for(unsigned int i = 0; i < dimX*dimY; i++) { *pubuffer++ = *buffer; *pubuffer++ = *buffer; *pubuffer++ = *buffer++; } imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888); } else if( gimage.GetPixelFormat() == gdcm::PixelFormat::INT16 ) { // We need to copy each individual 16bits into R / G and B (truncate value) short *buffer16 = (short*)buffer; unsigned char *ubuffer = new unsigned char[dimX*dimY*3]; unsigned char *pubuffer = ubuffer; for(unsigned int i = 0; i < dimX*dimY; i++) { // Scalar Range of gdcmData/012345.002.050.dcm is [0,192], we could simply do: // *pubuffer++ = *buffer16; // *pubuffer++ = *buffer16; // *pubuffer++ = *buffer16; // instead do it right: *pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255); *pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255); *pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255); buffer16++; } imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888); } else { std::cerr << "Pixel Format is: " << gimage.GetPixelFormat() << std::endl; return false; } } else { std::cerr << "Unhandled PhotometricInterpretation: " << gimage.GetPhotometricInterpretation() << std::endl; return false; } return true; } int main(int argc, char *argv[]) { if( argc < 2 ) { return 1; } const char *filename = argv[1]; const char *outfilename = argv[2]; gdcm::ImageReader ir; ir.SetFileName( filename ); if(!ir.Read()) { //Read failed return 1; } std::cout<<"Getting image from ImageReader..."< vbuffer; vbuffer.resize( gimage.GetBufferLength() ); char *buffer = &vbuffer[0]; QImage *imageQt = NULL; if( !ConvertToFormat_RGB888( gimage, buffer, imageQt ) ) { return 1; } QImageWriter writer; writer.setFormat("png"); writer.setFileName( outfilename ); if( !writer.write( *imageQt ) ) { return 1; } return 0; }