dcmtk with QT

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
VHonnet
Posts: 7
Joined: Mon, 2005-01-10, 17:11

dcmtk with QT

#1 Post by VHonnet »

I'm trying to show dicom images in a QT widget. I don't get it. Help !

Vincent

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#2 Post by Jörg Riesmeier »

We did this some time ago for monochrome images.

Here's our approach:
  1. getOutputData() from DicomImage object
  2. create PGM format in memory (add simple header)
  3. create QPixmap object
  4. loadFromData() into QPixmap object
  5. drawPixmap() on QPainter object
That's all. There are probably better ways, but this has proven to work.

VHonnet
Posts: 7
Joined: Mon, 2005-01-10, 17:11

#3 Post by VHonnet »

But how do you create a PGM Format ?

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#4 Post by Jörg Riesmeier »

Here the relevant part of the code:

Code: Select all

QPixmap *pixmap = NULL;
DicomImage *image = /* ... */
if ((image != NULL) && (image->getStatus() == EIS_Normal))
{
    /* get image extension */
    const int width = (int)(image->getWidth());
    const int height = (int)(image->getHeight());
    char header[32];
    /* create PGM header */
    sprintf(header, "P5\n%i %i\n255\n", width, height);
    const int offset = strlen(header);
    const unsigned int length = width * height + offset;
    /* create output buffer for DicomImage class */
    Uint8 *buffer = new Uint8[length];
    if (buffer != NULL)
    {
        /* copy PGM header to buffer */
        OFBitmanipTemplate<Uint8>::copyMem((const Uint8 *)header, buffer, offset);
        if (image->getOutputData((void *)(buffer + offset), length, 8))
        {
            pixmap = new QPixmap;
            /* load PGM image from buffer */
            if (pixmap != NULL)
            {
                /* optimize for speed */
                pixmap->setOptimization(QPixmap::BestOptim);
                if (!pixmap->loadFromData((const unsigned char *)buffer, length, "PGM", Qt::AvoidDither))
                {
                    delete pixmap;
                    pixmap = NULL;
                }
            }
        }
        /* delete temporary pixel buffer */
        delete[] buffer;
    }
}

VHonnet
Posts: 7
Joined: Mon, 2005-01-10, 17:11

#5 Post by VHonnet »

Thanks a lot !!

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#6 Post by Géant Vert »

how displays the *QPixmap?

I try to display a way of a QLabel but "label->setPixmap(pixmap)" isn't good :).

What must I do? Can you explain please

thank

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#7 Post by Géant Vert »

I succeed to display a bmp. But this code doesn't run.

DicomImage *image=NULL;
image = new DicomImage(nameFile);
image->writeBMP("te.bmp",8,0); //i create a bmp
QPixmap pixmap("te.bmp");
labeldisplay->setPixmap(pixmap) ;


"nameFile" is the adress of the file ("D:/image/test.dcm")

if you can help me, thank.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#8 Post by Jörg Riesmeier »

how displays the *QPixmap?
Some years ago I was using QPainter::drawPixmap() in the PaintEvent of a QWidget:

Code: Select all

void KVImageViewer::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    /* set clipping region (allows optimization if available) */
    painter.setClipRegion(event->region());
    /* draw image(s) */
    for (int i = 0; i < MAX_IMAGES_PER_WINDOW; i++)
    {
        /* check for valid pixmap */
        if (ImageData[i] != NULL)
        {
            /* create qt pixmap of requested size */
            QPixmap *pixmap = ImageData[i]->getScaledPixmap(ImageRect[i].size());
            if (pixmap != NULL)
            {
                /* draw pixmap at specified position */
                painter.drawPixmap(ImageRect[i].topLeft(), *pixmap);
            } else {
                /* print error message */
                KVUtils::printErrorMessage(LogStream, "cannot create scaled pixmap for screen output");
            }
        }
    }
}

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#9 Post by Géant Vert »

DicomImage *imageDic=NULL;
imageDic = new DicomImage
(&fileformat,xfer,CIF_MayDetachPixelData );
if(imageDic->getStatus()==EIS_Normal)


When i use getStatus, it equalize to EIS_NoDataDictionnary.
Must I load a .dic before to display an image?
Must I find the format of image to use writeBMP function? (ex: jpeg,bmp,etc....)

ps:I have a .dic in the lib dcmtk directory.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#10 Post by Jörg Riesmeier »

If you are using Unix, make sure that the data dictionary "dicom.dic" is stored in the default path. Alternatively, you could use the environment variable DCMDICTPATH to specify the path to the dictionary. More details can be found in the documentation (e.g. "datadict.txt").

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#11 Post by Géant Vert »

Thanks since I create the variable environement, It runs. ;)

Next step read the pixeldata in memory without to create a external file.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#12 Post by Jörg Riesmeier »

Next step read the pixeldata in memory without to create a external file.
See example in the documentation. The rest (create a PGM image in memory) is describe above in this discussion thread.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#13 Post by Géant Vert »

I do it and it 's good. But I can't read dicom image colour. is there a solution to display colour image?

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#14 Post by Jörg Riesmeier »

In order to add support for DICOM color images to class DicomImage, you just have to include "diregist.h" into your application (see source code example in DCMTK's documentation). And of course, you'll have to change the way the color bitmap is delivered to the Qt image/pixmap classes (e.g. create a PPM image in memory instead of a PGM image).

Maybe, there is a better or more efficient way of cooperation with Qt but the above described approach is known to work (at least for monochrome images).

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#15 Post by Géant Vert »

thank again. It 's easy to read coloured image. Here the code:

sprintf(header, "P6\n%i %i\n255\n", width, height); //entéte du PPM format image non compressé
const int offset = strlen(header); //on prend la longueur de l'entéte
const unsigned int length = width * height*3 + offset; //on multiplie par 3 car il on a 3 composante couleur
// create output buffer for DicomImage class
Uint8 *buffer = new Uint8[length];
if (buffer != NULL)
{
// copy PGM header to buffer
OFBitmanipTemplate<Uint8>::copyMem((const Uint8 *)header, buffer, offset);
imageDic->getOutputData((void *)(buffer + offset), length, 8);
QPixmap *pixmap = new QPixmap;
pixmap->loadFromData((const unsigned char *)buffer, length, "PPM", Qt::AvoidDither);
// load PGM image from buffer
if (pixmap != NULL)
{
if (!pixmap->loadFromData((const unsigned char *)buffer, length, "PPM", Qt::AvoidDither))
{
// delete pixmap;
pixmap = NULL;
}
// labeldisplay->setScaledContents (true );
labeldisplay->setPixmap(*pixmap) ;

// delete temporary pixel buffer
delete[] buffer;


But not all dicom file are readable.
How can i Know if the dicom image is an jpeg or bmp (compressed format)?

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 1 guest